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