upcoj 2174 二维树状数组
简单的树状数组题,从题意可知,由于N太大,直接模拟操作复杂度太高,则利用树状数组的logn算法。
树状数组我只做过一题,然后拿之前的模板来做二维的,没啥难的。
结果abs()里面用了int CE了一次,没注意用了cinTLE了一次,简直傻逼- -。。。
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; const int maxt=1025; int N; int ar[maxt][maxt]; //数状数组 int c[maxt][maxt]; //模拟图 int lowbit(int t) //位运算,求最小幂2^k的k { return t&(-t); } void add(int j,int t,int v) //对元素进行加法操作 { for(int i=t;i<=maxt;i+=lowbit(i)) { ar[j][i]+=v; } } int sum(int j,int t) { int s=0; for(int i=t;i>0;i-=lowbit(i)) { s+=ar[j][i]; } return s; } int sumt(int x,int y) { int sumx=0; for(int k=1;k<=x;k++) //x为数组个数 { sumx+=sum(k,y); //求和 } return sumx; } int main() { memset(ar,0,sizeof(ar)); memset(c,0,sizeof(c)); for(int k=1;k<maxt;k++) for(int i=1;i<maxt;i++) //从1开始 { //A为1 //B 为0 if(k%2==1) //k奇数 A为奇数 { if(i%2==1) { add(k,i,1); c[k][i]=1; //加个模拟 } } if(k%2==0) //k偶数,A为偶数 { if(i%2==0) { add(k,i,1); c[k][i]=1; } } } scanf("%d",&N); getchar(); /*for(int i=1;i<=3;i++) { cout<<endl; for(int j=1;j<=3;j++) { cout<<c[i][j]<<' '; } } cout<<endl;*/ while(N--) { //cout<<N<<endl; char flag; //两种情况 一个是查询 scanf("%c",&flag); if(flag=='R') { int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); //cout<<sumt(x2,y2)<<' '<<sumt(x1-1,y1-1)<<' '<<sumt(x1-1,y2)<<' '<<sumt(x2,y1-1)<<endl; int tmp1=sumt(x2,y2)+sumt(x1-1,y1-1)-sumt(x1-1,y2)-sumt(x2,y1-1); // 1的个数 //int tmp1=abs(sumt(x2,y2)-sumt(x1,y1)); int tmp2=((y2-y1)+1)*((x2-x1)+1); //总数 tmp2=tmp2-tmp1; printf("%d %d\n",tmp1,tmp2); } int tmp; if(flag=='A') //修改操作 { int x,y; tmp=1; scanf("%d%d",&x,&y); if(c[x][y]!=tmp) { add(x,y,1); c[x][y]=tmp; } } if(flag=='B') { int x,y; tmp=0; scanf("%d%d",&x,&y); if(c[x][y]!=tmp) { add(x,y,-1); c[x][y]=tmp; } } getchar(); } return 0; }