Matrix.(POJ-2155)(树状数组)
来源:互联网 发布:个人所得税网络申报 编辑:程序博客网 时间:2024/05/23 01:26
一道二维树状数组的题目,比较经典,适合新手练习。
之前刚开始搞ACM的时候,对树状数组一知半解的状态下看别人代码写的这道题,其实根本没有理解,而且题意都搞错了。
操作有2种: 翻转一个矩形和查询一个格子的值是0还是1 。 怎么办呢? 操作次数非常多,n也很大,肯定不能把矩形老老实实该一遍。
其实我们可以将问题简化,先看一维问题,将一段0、1序列进行如下操作。那么每次转置一段序列,其实可以只改变两个端点,这样的话在区间内的任何一点,它之前的所有数字只和一定和在区间外的情况恰好不同, 现在迁移到二维也是一样的道理, 大家可以看一下这里:点击打开链接
那么问题就变成了区间求和和单点修改问题了。 我们每次修改所给矩形4个顶点的值的奇偶性就OK了。
x2+1和y2+1是为了让右下顶点包含在矩形之中。
细节参见代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<map>using namespace std;int T,n,m,bit[1005][1005];char s[10];int sum(int a,int b) { int s = 0; for(int i=a;i>0;i-=i&-i) for(int j=b;j>0;j-=j&-j) s+=bit[i][j]; return s;}void add(int a,int b) { for(int i=a;i<=n;i+=i&-i) for(int j=b;j<=n;j+=j&-j){ bit[i][j]++; }}int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(bit,0,sizeof(bit)); while(m--) { scanf("%s",s); if(s[0]=='C'){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); add(x2+1,y2+1); add(x1,y1); add(x1,y2+1); add(x2+1,y1); } else { int x,y; scanf("%d%d",&x,&y); printf("%d\n",sum(x,y)%2); } } if(T) printf("\n"); } return 0;}
1 0
- poj 2155 Matrix(二维树状数组)
- POJ 2155 Matrix (二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- poj - 2155 - Matrix(树状数组)
- 【树状数组(二维)】poj 2155 Matrix
- POJ 2155 Matrix (二维树状数组)
- [poj 2155] Matrix(二维树状数组)
- POJ 2155 Matrix (二维树状数组)
- POJ 2155 Matrix(树状数组)
- Matrix.(POJ-2155)(树状数组)
- POJ 2155 Matrix(二维树状数组)
- poj 2155 Matrix(树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix (树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- POJ 2155 Matrix(二维树状数组)
- [POJ 2155] Matrix (二维树状数组)
- 如何降低代码的耦合
- ubuntu查找自己想要的函数库
- (一)利用system()函数创建和删除文件夹
- jdk和jre的区别
- 我为什么做不了科研??
- Matrix.(POJ-2155)(树状数组)
- UVA 348 经典dp
- 【codechef】Nikhil and Commands(字符串删减,分类)
- iOS开源库
- eclipse老是报ThreadPoolExecutor$Worker.run()
- 3.3 最长公共子序列
- 创业投资分析
- 导入github上项目的方法
- 把数组排成最小的数