POJ 2155 Matrix (二维树状数组)题解
2024-10-18 16:33:05
思路:
没想到二维树状数组和一维的比只差了一行,update单点更新,query求和
这里的函数用法和平时不一样,query直接算出来就是某点的值,怎么做到的呢?
我们在更新的时候不止更新一个点,而是四个点,这样就会变成下图这样的效果
看不懂听我讲一下...这和上次嘉诚讲过的差分数组有点像(自觉回顾讲过什么),既然单点更新更新完是(1,1)~(x,y)的和在改变,那么我们只要在区间后面减去增加的,那么我们一算求和就等于求这个点的值了。我们要更新的实际上是黑框内区域,但是我们只更新(x1,y1)就只更新了红框区域,所以更新时多出来的三个点就是绿色的三块区域,因为是翻转问题,所以翻偶数次就是等于没翻,可以看到,最后绿色区域算上叠加都翻了偶数次,所以就抵消了。
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 1000+5;
int bit[N][N],n;
int lowbit(int x){
return x&(-x);
}
void update(int a,int b){
for(int i = a;i <= n;i += lowbit(i)){
for(int j = b;j <= n;j += lowbit((j))){
bit[i][j]++;
}
}
}
int query(int a,int b){
int ret = 0;
for(int i = a;i > 0;i -= lowbit(i)){
for(int j = b;j > 0;j -= lowbit(j)){
ret += bit[i][j];
}
}
return ret;
}
int main(){
int T,q,a,b,c,d;
char o[2];
scanf("%d",&T);
while(T--){
memset(bit,0,sizeof(bit));
scanf("%d%d",&n,&q);
for(int i = 0;i < q;i++){
scanf("%s",o);
if(o[0] == 'Q'){
scanf("%d%d",&a,&b);
printf("%d\n",(query(a,b) - ) % 2);
}
else{
scanf("%d%d%d%d",&a,&b,&c,&d);
update(a,b);
update(c+1,b);
update(a,d+1);
update(c+1,d+1);
}
}
if(T) printf("\n");
}
return 0;
}
最新文章
- CMakeLists.txt
- Python自动化 【第八篇】:Python基础-Socket编程进阶
- C语言中strdup函数使用方法
- About Inside the Azure Storage Outage of November 18th
- MySQL —— 程序连接时的驱动名称和URL
- MATLAB中如何使用遗传算法
- 【python】dir(__builtins__)查看python中所用BIF(内置函数)
- mysql 查询重复的(不区分大小写)数据的SQL优化
- pycURL的内存问题
- POJ1300(欧拉回路)
- koahub.js 0.09 发布,新增钩子机制
- 容斥原理、欧拉函数、phi
- 阅读github上的项目源码
- zoj3707(Calculate Prime S)解题报告
- OC 对象和函数
- tp5链接访问
- ACM需要掌握算法
- oracle之trunc(sysdate)
- react之echarts数据更新
- 配置一个nginx+php-fpm的web服务器