Description
Input
Output
Sample Input
3 4
1 2 3
1 0 0
1 0 0
2 1
0 1
2 2
2 1
Sample Output
3
6
2
Data Constraint
分析:
显然不可能是考平衡树,图都放出来了。
有一个结论是,平衡树旋转后,中序遍历不变。
因为修改一个点,权值和只有两个点改变,而力量值的积有一些点改变。我们用线段树维护一段区间的积。设
x
x
节点的中序遍历值为,查询的区间就是
[dfnx−sizelson,dfnx+sizerson]
[
d
f
n
x
−
s
i
z
e
l
s
o
n
,
d
f
n
x
+
s
i
z
e
r
s
o
n
]
对于旋转操作,维护树的形态以及子树大小,把修改了权值和的点,也就是
x
x
和的新权值插入线段树,查询直接线段树区间查询即可。
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#define LL long long
const int maxn=2e5+7;
const LL mod=1e9+7;
using namespace std;
int dfn[maxn],size[maxn],l[maxn],r[maxn],fa[maxn];
LL sum[maxn],w[maxn],t[maxn*4];
int n,test,op,x,cnt;
void dfs(int x)
{
size[x]=1;
sum[x]=w[x];
if (l[x]) dfs(l[x]),fa[l[x]]=x;
sum[x]+=sum[l[x]];
size[x]+=size[l[x]];
dfn[x]=++cnt;
if (r[x]) dfs(r[x]),fa[r[x]]=x;
sum[x]+=sum[r[x]];
size[x]+=size[r[x]];
}
void ins(int p,int l,int r,int x,LL k)
{
if (l==r)
{
t[p]=k%mod;
return;
}
int mid=(l+r)/2;
if (x<=mid) ins(p*2,l,mid,x,k);
else ins(p*2+1,mid+1,r,x,k);
t[p]=t[p*2]*t[p*2+1]%mod;
}
LL getmul(int p,int l,int r,int x,int y)
{
if ((l==x) && (r==y)) return t[p];
int mid=(l+r)/2;
if (y<=mid) return getmul(p*2,l,mid,x,y);
else if (x>mid) return getmul(p*2+1,mid+1,r,x,y);
else return getmul(p*2,l,mid,x,mid)*getmul(p*2+1,mid+1,r,mid+1,y)%mod;
}
int main()
{
freopen("splay.in","r",stdin);
freopen("splay.out","w",stdout);
scanf("%d%d",&n,&test);
for (int i=1;i<=n;i++)
{
scanf("%lld%d%d",&w[i],&l[i],&r[i]);
}
dfs(1);
for (int i=1;i<=n;i++) ins(1,1,n,dfn[i],sum[i]);
for (int i=1;i<=test;i++)
{
scanf("%d%d",&op,&x);
if (op==0)
{
int y=l[x];
if (y)
{
l[x]=r[y];
if (r[y]) fa[r[y]]=x;
if (fa[x])
{
if (l[fa[x]]==x) l[fa[x]]=y;
else r[fa[x]]=y;
}
fa[y]=fa[x];
fa[x]=y;
r[y]=x;
size[x]=size[l[x]]+size[r[x]]+1;
size[y]=size[l[y]]+size[r[y]]+1;
sum[x]=sum[l[x]]+sum[r[x]]+w[x];
sum[y]=sum[l[y]]+sum[r[y]]+w[y];
ins(1,1,n,dfn[x],sum[x]);
ins(1,1,n,dfn[y],sum[y]);
}
}
if (op==1)
{
int y=r[x];
if (y)
{
r[x]=l[y];
if (l[y]) fa[l[y]]=x;
if (fa[x])
{
if (l[fa[x]]==x) l[fa[x]]=y;
else r[fa[x]]=y;
}
fa[y]=fa[x];
fa[x]=y;
l[y]=x;
size[x]=size[l[x]]+size[r[x]]+1;
size[y]=size[l[y]]+size[r[y]]+1;
sum[x]=sum[l[x]]+sum[r[x]]+w[x];
sum[y]=sum[l[y]]+sum[r[y]]+w[y];
ins(1,1,n,dfn[x],sum[x]);
ins(1,1,n,dfn[y],sum[y]);
}
}
if (op==2)
{
printf("%lld\n",getmul(1,1,n,dfn[x]-size[l[x]],dfn[x]+size[r[x]]));
}
}
}