您的位置:首页 > 其它

POJ-2155 树状数组初学习

2015-08-01 09:41 323 查看
#include<iostream>
#include<cstring>
using namespace std;
const int MAX_N = 1005;
int NUM,TEST;
int tree[MAX_N][MAX_N];
void Getsum(int x,int y)
{
    for(int i=x; i>0; i-=(i&-i))
        for(int j=y; j>0; j-=(j&-j))
            tree[i][j]^=1;
}
int Update(int x,int y)
{
    int res=0;
    for(int i=x;i<=NUM;i+=(i&-i))
        for(int j=y;j<=NUM;j+=(j&-j))
        res+=tree[i][j];
    return res%2;
}
int main()
{
    std::ios::sync_with_stdio(false);
    int kase,a,b,c,d;
    char C;
    cin>>kase;
    while(kase--)
    {
        cin>>NUM>>TEST;
        memset(tree,0,sizeof(tree));
        while(TEST--)
        {
            cin>>C>>a>>b;
            if(C=='C')
            {
                cin>>c>>d;
                Getsum(a-1,b-1);
                Getsum(c,d);
                Getsum(c,b-1);
                Getsum(a-1,d);
            }
            else
                cout<<Update(a,b)<<endl;

        }
        cout<<endl;
    }
    return 0;
}

此题输入量较大,必须关闭流同步;

题解来自于:http://blog.sina.com.cn/s/blog_6a16f43f0100m7fw.html

(1)经典的二维树状数组

这道题跟一般的树状数组操作有点不同,它是修改一片区域的值,求的是其中的一个点,我们可以这样来想!!

当我们修改一片区域的时候,我们可以分段去修改,也就是想当于树状数组中的 Getsum(x,y)

当我们求其中的一个点的时候,我们可以变为统计这个点的翻转次数,凡是跟这个点相关的区间都要统计一下,

比如说在一维的情况中,

我们要使区间(a, b)内的点 + c,只需要使区间(1, b)内的点+c,而区间(1, a-1)内的点-c即可。

如果是二维的,修改矩阵(x1, y1)到(x2, y2),即(x2, y2)+c, (x1-1,y2)-c, (x2, y1-1)-c, (x1-1,y1-1)+c。



即我们可以用Getsum(x, c)修改(1, x)这个区间内的点的值,而用Update(x)来求该点的值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: