二维线段树

二维线段树,稍微学了一下,写个博客,留个板子,日后忘了看。
二维线段树,树套数写法,四叉树没写

HDU——4819

单点更新,区间查询最大值最小值。

#include
using namespace std;
typedef long long ll;
const int N=1005;
int maxx[N*4][N*4],minn[N*4][N*4],a[N][N];
int n,m,Mx,Mi;
void pushup(int px,int py) {
	maxx[px][py]=max(maxx[px][py*2],maxx[px][py*2+1]);
	minn[px][py]=min(minn[px][py*2],minn[px][py*2+1]);
}
void buildy(int py,int l,int r,int px,int x) {
	if(l==r) {
		if(x!=-1) {
			maxx[px][py]=a[x][l];
			minn[px][py]=a[x][l];
		} else {
			maxx[px][py]=max(maxx[px*2][py],maxx[px*2+1][py]);
			minn[px][py]=min(minn[px*2][py],minn[px*2+1][py]);
		}
		return;
	}
	int mid=(l+r)/2;
	buildy(py*2,l,mid,px,x);
	buildy(py*2+1,mid+1,r,px,x);
	pushup(px,py);
}
void buildx(int px,int l,int r) {
	if(l==r) {
		buildy(1,1,n,px,l);
		return;
	}
	int mid=(l+r)/2;
	buildx(px*2,l,mid);
	buildx(px*2+1,mid+1,r);
	buildy(1,1,n,px,-1);
}
void changey(int py,int l,int r,int px,int x,int y,int val) {
	if(l==r) {
		if(x!=-1) {
			maxx[px][py]=val;
			minn[px][py]=val;
		} else {
			maxx[px][py]=max(maxx[px*2][py],maxx[px*2+1][py]);
			minn[px][py]=min(minn[px*2][py],minn[px*2+1][py]);
		}
		return;
	}
	int mid=(l+r)/2;
	if(y<=mid)changey(py*2,l,mid,px,x,y,val);
	else changey(py*2+1,mid+1,r,px,x,y,val);
	pushup(px,py);
}
void changex(int px,int l,int r,int x,int y,int val) {
	if(l==r) {
		changey(1,1,n,px,x,y,val);
		return;
	}
	int mid=(l+r)/2;
	if(x<=mid)changex(px*2,l,mid,x,y,val);
	else changex(px*2+1,mid+1,r,x,y,val);
	changey(1,1,n,px,-1,y,val);
}
void asky(int py,int l,int r,int px,int L,int R) {
	if(L<=l&&r<=R) {
		Mx=max(Mx,maxx[px][py]);
		Mi=min(Mi,minn[px][py]);
		return;
	}
	int mid=(l+r)/2;
	if(L<=mid)asky(py*2,l,mid,px,L,R);
	if(R>mid)asky(py*2+1,mid+1,r,px,L,R);
}
void askx(int px,int l,int r,int L,int R,int U,int D) {
	if(L<=l&&r<=R) {
		asky(1,1,n,px,U,D);
		return;
	}
	int mid=(l+r)/2;
	if(L<=mid)askx(px*2,l,mid,L,R,U,D);
	if(R>mid)askx(px*2+1,mid+1,r,L,R,U,D);
}
int main() {
	int T;
	scanf("%d",&T);
	for(int cas=1; cas<=T; ++cas) {
		scanf("%d",&n);
		for(int i=1; i<=n; ++i) {
			for(int j=1; j<=n; ++j) {
				scanf("%d",&a[i][j]);
			}
		}
		buildx(1,1,n);
		printf("Case #%d:\n",cas);
		scanf("%d",&m);
		while(m--) {
			int x,y,len;
			scanf("%d %d %d",&x,&y,&len);
			int l=x-len/2;
			int r=x+len/2;
			int u=y-len/2;
			int d=y+len/2;
			if(l<1)l=1;
			if(r>n)r=n;
			if(u<1)u=1;
			if(d>n)d=n;
			Mx=-1,Mi=2e9;
			askx(1,1,n,l,r,u,d);
			int mid=(Mx+Mi)/2;
			printf("%d\n",mid);
			changex(1,1,n,x,y,mid);
		}
	}
	return 0;
}

洛谷——P3688

动态开点,区间更新,单点查询,标记永久化。

#include
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const int N = 2e5 + 500;
int n,m;
int tot,root[N*4];
struct tree {
	int l,r;
	ll data;
} t[N*400];
ll quick(ll a,ll b) {
	ll ans=1;
	while(b) {
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
ll cal(ll p,ll q) {
	ll ans=p*q%mod;
	ans=(ans+(1-q)*(1-p)%mod)%mod;
	ans=(ans+mod)%mod;
	return ans;
}
void changey(int &p,int l,int r,int L,int R,ll val) {
	if(!p) {
		p=++tot;
		t[p].data=1ll;
	}
	if(L<=l&&r<=R) {
		t[p].data=cal(t[p].data,val);
		return;
	}
	int mid=(l+r)/2;
	if(L<=mid)changey(t[p].l,l,mid,L,R,val);
	if(R>mid)changey(t[p].r,mid+1,r,L,R,val);
}
void changex(int p,int l,int r,int L,int R,int U,int D,ll val) {
	if(L<=l&&r<=R) {
		changey(root[p],1,n,U,D,val);
		return;
	}
	int mid=(l+r)/2;
	if(L<=mid)changex(p*2,l,mid,L,R,U,D,val);
	if(R>mid)changex(p*2+1,mid+1,r,L,R,U,D,val);
}
ll asky(int p,int l,int r,int x) {
	if(!p)return 1;
	if(l==r) {
		return t[p].data;
	}
	int mid=(l+r)/2;
	if(x<=mid)return cal(t[p].data,asky(t[p].l,l,mid,x));
	else return cal(t[p].data,asky(t[p].r,mid+1,r,x));
}
ll askx(int p,int l,int r,int x,int y) {
	if(l==r) {
		return asky(root[p],1,n,y);
	}
	int mid=(l+r)/2;
	if(x<=mid)return cal(askx(p*2,l,mid,x,y),asky(root[p],1,n,y));
	else return cal(askx(p*2+1,mid+1,r,x,y),asky(root[p],1,n,y));
}
int main() {
	scanf("%d %d",&n,&m);
	while(m--) {
		int op,x,y;
		scanf("%d %d %d",&op,&x,&y);
		if(op == 1) {
			ll q=quick(1ll*(y-x+1),mod-2);
			if(x>1)changex(1,0,n,1,x-1,x,y,(1-q+mod)%mod),changex(1,0,n,0,0,1,x-1,0);
			if(y<n)changex(1,0,n,x,y,y+1,n,(1-q+mod)%mod),changex(1,0,n,0,0,y+1,n,0);
			changex(1,0,n,x,y,x,y,(1-2ll*q+mod)%mod),changex(1,0,n,0,0,x,y,q);
		} else {
			printf("%lld\n",askx(1,0,n,x-1,y));
		}
	}
	return 0;
}

你可能感兴趣的:(数据结构)