计数问题【JSOI2009】【树状数组三维单修区查】

版权声明:这是gigo写的QAQ https://blog.csdn.net/qq_42835815/article/details/85014287

传送门:https://www.luogu.org/problemnew/show/P4054

数据很小,支持开三维

三维分别是横纵坐标和权值

这样每次维护的时候只需要在d[x][y][key]++就行或者--。

基本也是模板,,注意一下差分那个地方,,经典的总-左-上+左上

#include<bits/stdc++.h>
#define in read()
using namespace std;
int in{
	int cnt=0,f=1;char ch=0;
	while(!isdigit(ch)){
		ch=getchar();
		if(ch=='-')f=-1;
	}
	while(isdigit(ch)){
		cnt=cnt*10+ch-48;
		ch=getchar();
	}
	return cnt*f;
} int n,m;int d[303][303][102];
int lowbit(int x){
	return x&(-x);
}
void update(int x,int y,int k,int val){
	int yy=y;
	while(x<=n){
		while(y<=m){
			d[x][y][k]+=val;
			y+=lowbit(y);
		}
		y=yy;
		x+=lowbit(x);
	}
}
int query(int x,int y,int c){
	int ans=0;
	int yy=y;
	while(x>0){
		while(y>0){
			ans+=d[x][y][c];
			y-=lowbit(y);
		}
		y=yy;
		x-=lowbit(x);
	}
	return ans;
}
int a[304][304],q;
int main(){
	n=in;m=in;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			a[i][j]=in;
			update(i,j,a[i][j],1);
		}
	}
	q=in;
	int opt,x1,x2,y1,y2,c;
	while(q--){
		opt=in;
		if(opt==1){
			x1=in;x2=in;c=in;
			update(x1,x2,c,1);
			update(x1,x2,a[x1][x2],-1);
			a[x1][x2]=c;
		}
		else{
			x1=in;x2=in;y1=in;y2=in;c=in;
			printf("%d\n",query(x2,y2,c)-query(x1-1,y2,c)-query(x2,y1-1,c)+query(x1-1,y1-1,c));
		}
	}
	return 0;
}

没有什么要注意的细节,,乱做就行

猜你喜欢

转载自blog.csdn.net/qq_42835815/article/details/85014287