• 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("
    ");
        }
    }
  • 相关阅读:
    JavaScript之链式结构序列化
    js 常用的正则表达式
    99%的人都理解错了HTTP中GET与POST的区别
    取代Promise的Generator生成器函数
    深入了解JavaScript权威指南
    限制input输入类型(多种方法实现)
    textillate.js 文字动画
    jQuery如何改变css伪元素样式
    保存android程序崩溃日志到SD卡
    跟我一起学extjs5(19--模块记录的拖放删除、拖放复制新增)
  • 原文地址:https://www.cnblogs.com/freinds/p/6422190.html
Copyright © 2020-2023  润新知