1. 程式人生 > >計數問題【JSOI2009】【樹狀陣列三維單修區查】

計數問題【JSOI2009】【樹狀陣列三維單修區查】

傳送門: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;
}

沒有什麼要注意的細節,,亂做就行