poj Matrix 2155 (树状数组&&二维线段树) 好题

Matrix
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 21791   Accepted: 8154

Description

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N).

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 the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case.

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

For each querying output one line, which has an integer representing A[x, y].

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
//第一次看到树状数组,还不太懂,先贴上代码
 
  
#include
#include
int n;
int s[1010][1010];
void getsum(int x,int y)
{
	int i,j;
	for(i=x;i>0;i-=(i&-i))
	{
		for(j=y;j>0;j-=(j&-j))
			s[i][j]^=1;
	}
}
int update(int x,int y)
{
	int i,j,ss=0;
	for(i=x;i<=n;i+=(i&-i))
	{
		for(j=y;j<=n;j+=(j&-j))
			ss+=s[i][j];
	}
	if(ss&1)
		return 1;
	return 0;
}
int main()
{
	int t,m,x1,x2,y1,y2,i,j;
	char c;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		memset(s,0,sizeof(s));
		while(m--)
		{
			getchar();
			scanf("%c%d%d",&c,&x1,&y1);
			if(c=='C')
			{
				scanf("%d%d",&x2,&y2);
				getsum(x1-1,y1-1);
				getsum(x2,y2);
				getsum(x2,y1-1);
				getsum(x1-1,y2);
			}
			if(c=='Q')
				printf("%d\n",update(x1,y1));
		}
		printf("\n");
	}
	return 0;
}

//线段树
 
  
#include 
#include 
#define xlson kx<<1, xl, mid
#define xrson kx<<1|1, mid+1, xr
#define ylson ky<<1, yl, mid
#define yrson ky<<1|1, mid+1, yr
#define MAXN 1005
#define mem(a) memset(a, 0, sizeof(a))
bool tree[MAXN<<2][MAXN<<2];
int  X, N, T;
int num, X1, X2, Y1, Y2;
char ch;
void editY(int kx,int ky,int yl,int yr)
{
    if(Y1<=yl&&yr<=Y2)
    {
        tree[kx][ky] = !tree[kx][ky];
        return ;
    }
    int mid=(yl+yr)>>1;
    if(Y1 <= mid) 
		editY(kx,ylson);
    if(Y2 >  mid) 
		editY(kx,yrson);
}
void editX(int kx,int xl,int xr)
{
    if(X1<=xl&&xr<=X2)
    {
        editY(kx,1,1,N);
        return ;
    }
    int mid=(xl+xr)>>1;
    if(X1<=mid) 
		editX(xlson);
    if(X2>mid) 
		editX(xrson);
}
void queryY(int kx,int ky,int yl,int yr)
{
    if(tree[kx][ky]) 
		num++;
    if(yl==yr) 
		return ;
    int mid =(yl+yr)>>1;
    if(Y1<=mid) 
		queryY(kx,ylson);
    else 
		queryY(kx,yrson);
}
void queryX(int kx,int xl,int xr)
{
    queryY(kx,1,1,N);
    if(xl==xr) 
		return ;
    int mid=(xl+xr)>>1;
    if(X1 <= mid)
		queryX(xlson);
    else  
		queryX(xrson);
}
int main()
{
    while(~scanf("%d",&X))
	while(X--)
    {
        mem(tree);
        scanf("%d%d",&N,&T);
        while(T--)
        {
        	getchar();
            scanf("%c%d%d",&ch,&X1,&Y1);
            if(ch == 'C')
            {
                scanf("%d%d", &X2, &Y2);
                editX(1,1,N);
            }
            else
            {
                num = 0;
                queryX(1,1,N);
                if(num & 1)
					printf("1\n");
                else 
					printf("0\n");
            }
        }
        if(X) printf("\n");
    }
    return 0;
}
 
//今天又写了一遍
#include
#include
#define N 1005
bool a[N<<2][N<<2];
int n,m,t,num;
int x1,x2,y1,y2;
char c;
void buildy(int kx,int ky,int yl,int yr)
{
	if(y1<=yl&&yr<=y2)
	{
		a[kx][ky]=!a[kx][ky];
		return ;
	}
	int mid=(yl+yr)/2;
	if(y1<=mid)
		buildy(kx,ky<<1,yl,mid);
	if(y2>mid)
		buildy(kx,ky<<1|1,mid+1,yr);
}
void buildx(int kx,int xl,int xr)
{
	if(x1<=xl&&xr<=x2)
	{
		buildy(kx,1,1,n);
		return ;
	}
	int mid=(xl+xr)/2;
	if(x1<=mid)
		buildx(kx<<1,xl,mid);
	if(x2>mid)
		buildx(kx<<1|1,mid+1,xr);
}
void queryy(int kx,int ky,int yl,int yr)
{
	if(a[kx][ky])
		num++;
	if(yl==yr)
		return ;
	int mid=(yl+yr)/2;
	if(y1<=mid)
		queryy(kx,ky<<1,yl,mid);
	else
		queryy(kx,ky<<1|1,mid+1,yr);
}
void queryx(int kx,int xl,int xr)
{
	queryy(kx,1,1,n);
	if(xl==xr)
		return ;
	int mid=(xl+xr)/2;
	if(x1<=mid)
		queryx(kx<<1,xl,mid);
	else
		queryx(kx<<1|1,mid+1,xr);
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		memset(a,0,sizeof(a));
		scanf("%d%d",&n,&m);
		while(m--)
		{
			getchar();
			scanf("%c%d%d",&c,&x1,&y1);
			if(c=='C')
			{
				scanf("%d%d",&x2,&y2);
				buildx(1,1,n);
			}
			else
			{
				num=0;
				queryx(1,1,n);
				if(num&1)
					printf("1\n");
				else
					printf("0\n");
			}	
		}
		if(t)
			printf("\n");
	}
	return 0;
}


 
 

你可能感兴趣的:(poj,线段树,好题)