[线段树模拟平衡树] HDU4942. Game on S♂play
刚开始想用Splay、Treap什么的维护dfs序…打起来贼烦
打完后vectorxj大佬说用中序遍历就好了…
因为旋转后一棵树的中序遍历是不会变的,那么每次旋转就是改变了下子树在中序遍历中的区间,然后用线段树模拟一下就好了。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100010,P=1e9+7;
int t,n,m,cnt;
int l[N],r[N],L[N],R[N],v[N],w[N],p[N],Q[N],fa[N];
int pro[N<<2];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
void Up(int x){
v[x]=(1LL*w[x]+v[l[x]]+v[r[x]])%P;
}
void dfs(int x){
L[x]=cnt+1;
if(l[x]) dfs(l[x]);
p[x]=++cnt; Q[cnt]=x;
if(r[x]) dfs(r[x]);
R[x]=cnt;
Up(x);
}
void Build(int g,int l,int r){
if(l==r) return pro[g]=v[Q[l]],void();
int mid=l+r>>1;
Build(g<<1,l,mid); Build(g<<1|1,mid+1,r);
pro[g]=1LL*pro[g<<1]*pro[g<<1|1]%P;
}
void Modify(int g,int l,int r,int x,int y){
if(l==r) return pro[g]=y,void();
int mid=l+r>>1;
if(x<=mid) Modify(g<<1,l,mid,x,y);
else Modify(g<<1|1,mid+1,r,x,y);
pro[g]=1LL*pro[g<<1]*pro[g<<1|1]%P;
}
int Query(int g,int L,int R,int l,int r){
if(L==l && r==R) return pro[g];
int mid=L+R>>1;
if(r<=mid) return Query(g<<1,L,mid,l,r);
else if(l>mid) return Query(g<<1|1,mid+1,R,l,r);
else return 1LL*Query(g<<1,L,mid,l,mid)*Query(g<<1|1,mid+1,R,mid+1,r)%P;
}
int main(){
rea(t); int CASE=0;
while(t--){
rea(n); rea(m); cnt=0;
fa[1]=0;
for(int i=1;i<=n;i++)
rea(w[i]),rea(l[i]),rea(r[i]),fa[l[i]]=fa[r[i]]=i;
dfs(1);
Build(1,1,n);
printf("Case #%d:\n",++CASE);
while(m--){
int opt,x;
rea(opt); rea(x);
if(opt==0){
int y=l[x];
if(!y) continue;
if(fa[x]){
if(l[fa[x]]==x) l[fa[x]]=y; else r[fa[x]]=y;
}
fa[y]=fa[x];
if(l[x]=r[y]) fa[l[x]]=x;
fa[r[y]=x]=y;
Up(x); Up(y);
L[x]=p[y]+1; R[y]=R[x];
Modify(1,1,n,p[x],v[x]); Modify(1,1,n,p[y],v[y]);
}
else if(opt==1){
int y=r[x];
if(!y) continue;
if(fa[x]){
if(l[fa[x]]==x) l[fa[x]]=y; else r[fa[x]]=y;
}
fa[y]=fa[x];
if(r[x]=l[y]) fa[r[x]]=x; l[y]=x;
fa[x]=y;
Up(x); Up(y);
R[x]=p[y]-1; L[y]=L[x];
Modify(1,1,n,p[x],v[x]); Modify(1,1,n,p[y],v[y]);
}
else{
printf("%d\n",Query(1,1,n,L[x],R[x]));
}
}
}
return 0;
}
版权声明:本文为Coldef原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。