P4054 [JSOI2009]计数问题

P4054 [JSOI2009]计数问题

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;
}
原文地址:https://www.cnblogs.com/Akmaey/p/14648569.html