简单的树状数组题,从题意可知,由于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 为0if(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;
}