[POJ2155]Matrix(二维树状数组)

题目:http://poj.org/problem?id=2155

中文题意:

  给你一个初始全部为0的n*n矩阵,有如下操作

    1、C x1 y1 x2 y2 把矩形(x1,y1,x2,y2)上的数全部取反,1->0,0->1

    2、Q x y 求n*n矩阵的(x,y)位置上的数

题解;

  先看简单的:

    给你一个初始全为0的长度为n的序列,有如下操作

      1、C x y 把序列x到y位取反1->0,0->1

      2、Q x 求序列第x位的数

    做法很简单,设计一个数组a[],a[1..i]的和表示第i位数的值,对于C把第x位和第y+1位全部加上1,对于Q只要求出a[1..x]的和表示第x位置上的数,判断下                   奇偶就行了。如何快速处理呢,问题是对一个序列进行修改一个点并求出前缀和,很明显是标准的树状数组操作

  那么此题很容易发现就是上面那个一维的推广

    设计一个数组a[][],a[1..i][1..j]的和表示(i,j)位置上的数,对于C把(x1,y1),(x1,y2+1),(x2+1,y1),(x2+1,y2+1)4个位置的数加上1,对于Q求出a[1..i]             [1...j]的和,判断奇偶就行了。如何快速实现?修改单点+询问前缀矩阵和————>二维树状数组

 #include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=;
int c[maxn+][maxn+],n;
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
++c[i][j];
}
int getsum(int x,int y)
{
int ans=;
for(int i=x;i>;i-=lowbit(i))
for(int j=y;j>;j-=lowbit(j))
ans+=c[i][j];
return ans;
}
int main()
{ int t,m;
scanf("%d\n",&t);
while(--t>=)
{
memset(c,,sizeof(c));
scanf("%d %d\n",&n,&m);
while(--m>=)
{
char c;
scanf("%c ",&c);
if(c=='C')
{
int x1,y1,x2,y2;
scanf("%d %d %d %d\n",&x1,&y1,&x2,&y2);
add(x1,y1),add(x2+,y1),add(x1,y2+),add(x2+,y2+);
}
else
{
int x,y;
scanf("%d %d\n",&x,&y);
printf("%d\n",getsum(x,y)%);
}
}
printf("\n");
}
return ;
}

刷难题无力只能刷水了……

上一篇:「洛谷3338」「ZJOI2014」力【FFT】


下一篇:lintcode : 二叉树的最小深度