BZOJ1452 [JSOI2009]Count 树状数组
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1452
题意概括
一个n*m的矩阵,现在有2种操作:
- 修改某一个位置的值
- 求一个子矩阵某值的出现次数
n , m ≤ 300 , 1 ≤ 元素的值 ≤ 100 , 操作次数 ≤ 200000
题解
100棵二维树状数组。维护每个值的二维前缀出现次数。
好像该说的都说了……
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int N=300+5,C=100+5;
int n,m,q,a[N][N],t[C][N][N];
int lowbit(int x){
return x&-x;
}
void add(int c,int x,int y,int d){
for (int i=x;i<=n;i+=lowbit(i))
for (int j=y;j<=m;j+=lowbit(j))
t[c][i][j]+=d;
}
int sum(int c,int x,int y){
int ans=0;
for (int i=x;i>0;i-=lowbit(i))
for (int j=y;j>0;j-=lowbit(j))
ans+=t[c][i][j];
return ans;
}
int main(){
scanf("%d%d",&n,&m);
memset(t,0,sizeof t);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
add(a[i][j],i,j,1);
}
scanf("%d",&q);
while (q--){
int type,c;
scanf("%d",&type);
if (type==1){
int x,y;
scanf("%d%d%d",&x,&y,&c);
add(a[x][y],x,y,-1);
a[x][y]=c;
add(a[x][y],x,y,1);
}
else {
int x1,y1,x2,y2;
scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
printf("%d\n",sum(c,x2,y2)-sum(c,x1-1,y2)-sum(c,x2,y1-1)+sum(c,x1-1,y1-1));
}
}
return 0;
}
/*
3 3
1 2 3
3 2 1
2 1 3
3
2 1 2 1 2 1
1 2 3 2
2 2 3 2 3 2
*/

浙公网安备 33010602011771号