PKU 2155 Matrix(裸二维树状数组)

题目大意:原题链接

题意很简单,就不赘诉了。

解题思路:

使用二维树状数组,很裸的题。

二维的写起来也很方便,两重循环。

Add(int x,int y,int val)表示(x,y)-(n,n)矩形区域被修改val次(在传入参数时val=1)

如果是要修改(x1,y1)-(x2,y2)的矩形区域。

那么可以在(x1,y1)处加1,在(x2+1,y1)处加1,在(x1,y2+1)处加1,在(x2+1,y2+1)处加1,那么总共:

(x1,y1)-(x2,y2)矩形区域被修改1次,(x2+1,y1)-(n,n)矩形区域被修改2次;

(x1,y2+1)-(n,n)矩形区域被修改2次,(x2+1,y2+1)-(n,n)矩形区域被修改4次;

画个坐标图就知道了。而修改偶数次则回到初始状态,即为0;奇数次则变换一次,即为1。

Sum(int x,int y)表示由于(1,1)-(x,y)矩形区域内的点的改变导致点(x,y)被改变的次数求和,即:

点(x,y)被改变的总次数,而查询单点就是求和,再判断奇偶即可。

注意:真没想到cin,cout差别这么大,该题如果用cin,cout输入输出的话会超时。

之前关于这几个函数Add(x1,y1,1);Add(x2+1,y1,1);Add(x1,y2+1,1);Add(x2+1,y2+1,1);

中的坐标加1始终不理解,总感觉会多修改一些地方,现在一看一目了然(后来才知道是题意理解错了)。

C操作意思是要使得矩形区域(1,1)-(3,3)的查询结果为1就行,而不是使得m[i][j]非得变成1

                 图一和图三分别是坐标加1和不加1的查询结果;

            图二和图五分别对应着图一和图四的m[i][j]的变化过程;

            图三和图六分别对应着图一和图四的Sum(i,j)的变化过程

       很明显从图二可以看出,有些地方并没有真正的变成1,而查询结果却为1;

    不加1时修改的范围查询结果只在矩形区域(1,1)-(2,2),而加上1时则符合要求

  图一     图二         图三         图四         图五        图六

                  

                                       

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,T,m[1010][1010];
int lowbit(int x)
{
    return x&(-x);
}
int Sum(int x,int y)
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
            res+=m[i][j];
    return res;
}
void Add(int x,int y,int val)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=n;j+=lowbit(j))
            m[i][j]+=val;
}

int main()
{
    scanf("%d",&T);
    while(T--){
        int q;
        scanf("%d%d",&n,&q);
        memset(m,0,sizeof(m));
        char op;
        int x,y,x1,y1,x2,y2;
        while(q--){
            getchar();
            scanf("%c",&op);
            if(op=='C'){
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                Add(x1,y1,1);
                Add(x2+1,y1,1);
                Add(x1,y2+1,1);
                Add(x2+1,y2+1,1);
            }
            else{
                scanf("%d%d",&x,&y);
                if(Sum(x,y)%2==0) printf("0
");
                else printf("1
");
            }
        }
        if(T>0) printf("
");
    }
}
原文地址:https://www.cnblogs.com/freinds/p/6422190.html