P4054 [JSOI2009]计数问题
一道三维偏序就因为数据变成了三维树状数组的水题...
对每个权值开一个二维树状数组,然后暴力修改暴力询问即可。
view code
#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
x=0;char ch=getchar();bool f=false;
while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template <typename T>
inline void write(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
const int N=2e5+5,M=305;
#define y1 qwq
int n,m,a[M][M],ans[N],tree[105][M][M];
int lowbit(int x){return x&-x;}
void Add(int type,int x,int y,int v){while(x<=n){int now=y;while(now<=m){tree[type][x][now]+=v;now+=lowbit(now);}x+=lowbit(x);}}
int Ask(int type,int x,int y){
int tot=0;
while(x>=1){int now=y;while(now>=1){tot+=tree[type][x][now];now-=lowbit(now);}x-=lowbit(x);}
return tot;
}
int Query(int type,int x1,int y1,int x2,int y2){return Ask(type,x2,y2)+Ask(type,x1-1,y1-1)-Ask(type,x1-1,y2)-Ask(type,x2,y1-1);}
int main(){
int q,Top=0;
read(n),read(m);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(a[i][j]),Add(a[i][j],i,j,1);
read(q);
for(int i=1;i<=q;i++){
int op;read(op);
if(op==1){
int x,y,c;
read(x),read(y),read(c);
Add(a[x][y],x,y,-1),Add(c,x,y,1),a[x][y]=c;
}
else{
int x1,y1,x2,y2,c;
read(x1),read(x2),read(y1),read(y2),read(c);
ans[++Top]=Query(c,x1,y1,x2,y2);
}
}
for(int i=1;i<=Top;i++) write(ans[i]),putchar('
');
return 0;
}