藍橋杯訓練1
阿新 • • 發佈:2019-02-06
#include <Stdio.h> #include <math.h> #include <string.h> //因為本題n最大為10^5,如果按照正常的情況計算,會超時 //這裡採用了一個預處理的方式,將100000個數據,分成了100組, //分別維護了最大值和連續和。 const int N=1010; int f[1010][N]; int main() { int i,j,k,n,m; while(scanf("%d %d",&n,&m)!=EOF){ int r,c;r=(n-1)/1000+1;c=(n-(r-1)*1000)%1001;for(i=1;i<r;i++){ for(j=1;j<=1000;j++) scanf("%d",&f[i][j]); } for(j=1;j<=c;j++) scanf("%d",&f[i][j]);//輸入資料完畢; //進行預處理:求和等。 每行和儲存在f[1001]; __int64 num; for(i=1;i<r;i++){ num=0; for(j=1;j<=1000;j++) num=num+f[i][j]; f[i][1001]=num; }num=0; for(j=1;j<=c;j++) num=num+f[i][j]; f[i][1001]=num;//求和完畢; //下面預處理每段的最大值! int max; for(i=1;i<r;i++){ max=-1; for(j=1;j<=1000;j++) if(f[i][j]>max) max=f[i][j]; f[i][1002]=max; }max=-1; for(j=1;j<=c;j++) if(f[i][j]>max) max=f[i][j]; f[i][1002]=max; //下面進行輸入資料。 int p,x,y; while(m--){ if( m <0) break; scanf("%d %d %d",&p,&x,&y); r=(x-1)/1000+1;c=(x-(r-1)*1000)%1001; int r1,c1; if(p==1){ //同時需要維護和與最大值! f[r][1001]=f[r][1001]-f[r][c]+y; f[r][c]=y; //------------這裡最大值的錯了很多次, 應該將當前行重新全部掃描一邊! // 而且 f[r][1002] 也應該提前賦值為-1。 f[r][1002]=y; for(j=1;j<=1000;j++) if(f[r][j]>f[r][1002]) f[r][1002]=f[r][j]; } else if(p==2){ //計算x到y的和。 r1=(y-1)/1000+1;c1=(y-(r1-1)*1000)%1001; num=0; if(r==r1){ for(j=c;j<=c1;j++) num=num+f[r][j]; printf("%d\n",num); } else{ //在不同行; for(j=c;j<=1000;j++) num=num+f[r][j]; for(i=r+1;i<r1;i++) num=num+f[i][1001]; for(j=1;j<=c1;j++) num=num+f[r1][j]; printf("%d\n",num); } } else{ r1=(y-1)/1000+1;c1=(y-(r1-1)*1000)%1001; //輸出最大值。 max=-1; if(r==r1){ for(j=c;j<=c1;j++) if(f[r][j]>max) max=f[r][j]; } else{ for(j=c;j<=1000;j++) if(f[r][j]>max) max=f[r][j]; for(i=r+1;i<r1;i++) if(f[i][1002]>max) max=f[i][1002]; for(j=1;j<=c1;j++) if(f[r1][j]>max) max=f[r1][j]; } printf("%d\n",max); } } } return 0; }