Jzoj5662 尺树寸泓

平衡树的问题,很容易想到中序遍历

那么我们给每一个节点记录一下中序遍历中它子树所在的区间,一次旋转显然只会改变两个节点的值

对于询问我们用线段树区间求积就可以了

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 200010
#define M 1000000007
#define LL long long
#define mid (l+r>>1)
#define ls l,mid,x<<1
#define rs mid+1,r,x<<1|1
using namespace std;
int clk,n,m,l[N],r[N],v[N];
int w[N],wl[N],wr[N],p[N],s[N],rk[N],rt;
int T[N<<2];
inline void ps(int x){
	s[x]=(s[l[x]]+s[r[x]]+v[x])%M;
	wl[x]=(l[x]?wl[l[x]]:rk[x]);
	wr[x]=(r[x]?wr[r[x]]:rk[x]);
}
inline void dfs(int x){
	if(l[x]) dfs(l[x]);
	w[++clk]=x; rk[x]=clk;
	if(r[x]) dfs(r[x]);
	ps(x);
}
inline void build(int l,int r,int x){
	if(l==r){ T[x]=s[w[l]]; return; }
	build(ls);
	build(rs);
	T[x]=((LL)T[x<<1]*T[x<<1|1])%M;
}
inline void update(int l,int r,int x,int p,int k){
	if(l==r){ T[x]=k; return; }
	if(p<=mid) update(ls,p,k); else update(rs,p,k);
	T[x]=((LL)T[x<<1]*T[x<<1|1])%M;
}
inline LL query(int l,int r,int x,int L,int R){
	if(L<=l && r<=R) return T[x];
	LL ans=1;
	if(L<=mid) ans=ans*query(ls,L,R)%M;
	if(mid<R) ans=ans*query(rs,L,R)%M;
	return ans;
}
int main(){
	freopen("splay.in","r",stdin);
	freopen("splay.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d%d%d",v+i,l+i,r+i);
		p[l[i]]=i; p[r[i]]=i;
	}
	for(int i=1;i<=n;++i) if(!p[i]) rt=i;
	dfs(rt); 
	build(1,n,1);
	for(int o,x,y;m--;){
		scanf("%d%d",&o,&x);
		if(o==2) printf("%lld
",query(1,n,1,wl[x],wr[x]));
		else{
			if(!o&&l[x]){
				y=l[x]; o=p[x];
				l[x]=r[y]; r[y]=x; 
				if(l[x]) p[l[x]]=x; p[x]=y; p[y]=o;
				if(o){
					if(l[o]==x) l[o]=y; else r[o]=y;
				} else rt=y;
				ps(x); ps(y);
				update(1,n,1,rk[x],s[x]);
				update(1,n,1,rk[y],s[y]);
			} else if(o&&r[x]){
				y=r[x]; o=p[x];
				r[x]=l[y]; l[y]=x;
				if(r[x]) p[r[x]]=x; p[x]=y; p[y]=o;
				if(o){
					if(l[o]==x) l[o]=y; else r[o]=y;
				} else rt=y;
				ps(x); ps(y);
				update(1,n,1,rk[x],s[x]);
				update(1,n,1,rk[y],s[y]);
			}
		}
	}
} 

原文地址:https://www.cnblogs.com/Extended-Ash/p/9477107.html