Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 7121 | Accepted: 2657 |
Description
We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions.
1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2).
2. Q x y (1 <= x, y <= n) querys A[x, y].
Input
The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above.
Output
There is a blank line between every two continuous test cases.
Sample Input
1 2 10 C 2 1 2 2 Q 2 2 C 2 1 2 1 Q 1 1 C 1 1 2 1 C 1 2 1 2 C 1 1 2 2 Q 1 1 C 1 1 2 1 Q 2 1
Sample Output
1 0 0 1
Source
#include<stdio.h>
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
int n,sum;
struct Seg_Seg_Tree
{
int left,right;
bool val;
int mid() { return (left+right)>>1; }
};
struct Seg_Tree
{
int left,right;
Seg_Seg_Tree tt[1010*3];
int mid() { return(left+right)>>1;}
}tree[1010*3];
void build2(Seg_Seg_Tree t[],int left,int right,int idx)
{
t[idx].left=left;
t[idx].right=right;
t[idx].val=false;
if(left==right) return;
int mid=t[idx].mid();
build2(t,left,mid,LL(idx));
build2(t,mid+1,right,RR(idx));
}
void build(int left,int right,int idx)
{
build2(tree[idx].tt,1,n,1);
tree[idx].left=left;
tree[idx].right=right;
if(left==right) return;
int mid=tree[idx].mid();
build(left,mid,LL(idx));
build(mid+1,right,RR(idx));
}
void update2(Seg_Seg_Tree t[],int idx,int left,int right,int y1,int y2)
{
if(y1==left&&y2==right)
{
t[idx].val=!t[idx].val;
return;
}
int mid=t[idx].mid();
if (y2 <= mid) update2(t, LL(idx), left, mid, y1, y2);
else if (y1 > mid) update2(t, RR(idx), mid+1, right, y1, y2);
else
{
update2(t, LL(idx), left, mid, y1, mid);
update2(t, RR(idx), mid+1, right, mid+1, y2);
}
}
void update(int idx,int left,int right,int x1,int x2,int y1,int y2)
{
if(x1==left&&x2==right)
{
update2(tree[idx].tt,1,1,n,y1,y2);
return;
}
int mid=tree[idx].mid();
if (x2 <= mid) update(LL(idx), left, mid, x1, x2, y1, y2);
else if (x1 > mid) update(RR(idx), mid+1, right, x1, x2, y1, y2);
else
{
update(LL(idx), left, mid, x1, mid, y1, y2);
update(RR(idx), mid+1, right, mid+1, x2, y1, y2);
}
}
void query2(Seg_Seg_Tree t[],int idx,int first, int last,int y)
{
sum ^= t[idx].val;
if (first < last)
{
int mid = t[idx].mid();
if (y <= mid)
query2(t, LL(idx), first, mid, y);
else
query2(t, RR(idx), mid+1, last, y);
}
}
void query(int idx,int first,int last,int x,int y)
{
query2(tree[idx].tt,1,1,n,y);
if (first < last)
{
int mid = tree[idx].mid();
if (x <= mid)
query(LL(idx), first, mid, x, y);
else
query(RR(idx), mid+1, last, x, y);
}
}
int main()
{
int TT;
scanf("%d",&TT);
for(int j=0;j<TT;j++)
{
int t;
if(j>0) printf("/n");
scanf("%d%d",&n,&t);
build(1,n,1);
for(int i=1;i<=t;i++)
{
char str[10];
scanf("%s",str);
if(str[0]=='C')
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(1,1,n,x1,x2,y1,y2);
}
else
{
int x,y;
scanf("%d%d",&x,&y);
sum=0;
query(1,1,n,x,y);
printf("%d/n", sum);
}
}
}
return 0;
}
数组做法
#include <stdio.h>
#include <string.h>
#define MAXN 3010
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
int g[MAXN][MAXN],n,m,x,y,z,l,ans;
void updataY(int xid ,int id,int lf,int rg)
{
if( z<=lf && rg<=l)
{
if(g[xid][id]==1) g[xid][id]=0;
else g[xid][id]=1;
return;
}
int mid = ( lf + rg)>>1;
if( z < mid ) updataY(xid , LL(id) , lf ,mid);
if( mid < l ) updataY(xid ,RR(id), mid ,rg);
}
void updateX(int id,int lf,int rg)
{
if( x<=lf && rg<=y)
{
if(g[id][0]==-1) g[id][0]=0;
updataY( id , 1 , 0, n);
return;
}
int mid = ( lf + rg)>>1;
if(x<mid) updateX(LL(id),lf,mid);
if(mid<y) updateX(RR(id),mid,rg);
}
void queryY(int xid ,int id,int lf,int rg)
{
if( g[xid][id] != -1)
ans^=g[xid][id];
if( z<=lf && rg<=l) return;
int mid = ( lf + rg)>>1;
if( z < mid ) queryY(xid , LL(id), lf ,mid);
if( mid < l ) queryY(xid ,RR(id), mid ,rg);
}
void queryX(int id,int lf,int rg)
{
if( !g[id][0] ) queryY(id,1,0,n);
if( x<=lf && rg<=y) return ;
int mid = ( lf + rg)>>1;
if(x<mid) queryX(LL(id),lf,mid);
if(mid<y) queryX(RR(id),mid,rg);
}
int main()
{
int kase,f=0;
char in[10];
scanf("%d",&kase );
while( kase-- )
{
if(!f) f=1;
else puts("");
scanf("%d%d", &n, &m);
memset( g, -1, sizeof(g));
while(m--)
{
scanf("%s",in);
if( in[0] == 'C')
{
scanf("%d%d%d%d",&x,&z,&y,&l);
x--,z--;
updateX(1,0,n);
}
else
{
scanf("%d%d",&y,&l);
x=y-1;
z=l-1;
ans=0;
queryX(1,0,n);
printf("%d/n",ans);
}
}
}
return 0;
}