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)来求该点的值
相关文章推荐
- ubuntu下解决因为/boot磁盘空间不足导致无法更新
- EventBus :概述及基本概念 《一》
- Shiro学习(12)与Spring集成
- 随机生成UUID的工具类
- Win10 Mobile预览版10240模拟器图片讲解
- ubuntu安装 cober 笔记
- linux_c开发(5-1)进程间通讯_进程间通讯概念
- uva 11437
- RedHat6.1配置在线yum资源
- Objective-C中的instancetype和id区别
- Shiro学习(11)缓存机制
- Shiro学习(10)Session管理
- 第一个只出现一次的字符,josephus环,最大子数组和
- App开发。
- 抽象类与接口、内部类 8.1
- JavaScript 对象
- js中动态添加长字符串,并保持换行
- 设计模式 业务封装 & 紧耦合 vs. 松耦合 & 简单工厂模式
- Shiro学习(9)JSP标签
- iOS的SQLite的使用