[Splay][线段树] jzoj P5662 尺树寸泓

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

 

题解

  • 每次子树和只有 2 个点会修改
  • 旋转会导致统计子树的答案会比较麻烦
  • 而这是一棵平衡树,中序遍历在平衡树中的相对位置不会变
  • 而在中序遍历中,一个点的子树也是一个区间
  • 所以,我们可以把中序遍历搞出来,维护每个子树相对应的区间
  • 用线段树维护就可以了

代码

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define mo 1000000007
  6 using namespace std;
  7 struct data{ int l,r; }son[2000010];
  8 struct splay{ int l,r;long long mul; }tree[2000010*4];
  9 long long f[2000010],sum[2000010],a[2000010],fa[2000010],size[2000010],num[2000010],numl[2000010],ans;
 10 int n,q,opt,x,tot;
 11 void dfs(int x)
 12 {
 13     size[x]=1;
 14     if (son[x].l) dfs(son[x].l);
 15     num[++tot]=x; numl[x]=tot;
 16     if (son[x].r) dfs(son[x].r);
 17     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 18     f[x]=((f[son[x].l]*f[son[x].r])%mo*sum[x])%mo;
 19     size[x]+=size[son[x].l]+size[son[x].r];
 20 }
 21 void build(int dep,int l,int r)
 22 {
 23     tree[dep].l=l; tree[dep].r=r;
 24     if (l==r)
 25     {
 26         tree[dep].mul=sum[num[l]];
 27         return;
 28     }
 29     int mid=(l+r)/2;
 30     build(dep*2,l,mid);
 31     build(dep*2+1,mid+1,r);
 32     tree[dep].mul=(tree[dep*2].mul*tree[dep*2+1].mul)%mo;
 33 }
 34 void change(int dep,int l,int r,int x,int y)
 35 {
 36     if (l==r)
 37     {
 38         tree[dep].mul=y;
 39         return;
 40     }
 41     int mid=(l+r)/2;
 42     if (mid>=x) change(dep*2,l,mid,x,y);
 43     else change(dep*2+1,mid+1,r,x,y);
 44     tree[dep].mul=(tree[dep*2].mul*tree[dep*2+1].mul)%mo;   
 45 }
 46 void mul(int dep,int l,int r,int x,int y)
 47 {
 48     if (l==x&&y==r)
 49     {
 50         ans*=tree[dep].mul;
 51         ans=ans%mo;
 52         return;
 53     }
 54     int mid=(l+r)/2;
 55     if (y<=mid) mul(dep*2,l,mid,x,y);
 56     else if (x>mid) mul(dep*2+1,mid+1,r,x,y);
 57     else mul(dep*2,l,mid,x,mid),mul(dep*2+1,mid+1,r,mid+1,y);
 58 }
 59 int rrotate(int x)
 60 {
 61     int y=son[x].l;
 62     if (son[fa[x]].l==x) son[fa[x]].l=y; else son[fa[x]].r=y;
 63     int u=size[y];
 64     size[y]=size[x];
 65     size[x]=size[x]-u+size[son[y].r];
 66     fa[son[y].r]=x;
 67     fa[y]=fa[x];
 68     fa[x]=y;
 69     son[x].l=son[y].r;
 70     son[y].r=x;
 71     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 72     change(1,1,n,numl[x],sum[x]);
 73     sum[y]=(sum[son[y].l]+sum[son[y].r]+a[y])%mo;
 74     change(1,1,n,numl[y],sum[y]);
 75 }
 76 int lrotate(int x)
 77 {
 78     int y=son[x].r;
 79     if (son[fa[x]].l==x) son[fa[x]].l=y; else son[fa[x]].r=y;
 80     int u=size[y];
 81     size[y]=size[x];
 82     size[x]=size[x]-u+size[son[y].l];
 83     fa[son[y].l]=x;
 84     fa[y]=fa[x];
 85     fa[x]=y;
 86     son[x].r=son[y].l;
 87     son[y].l=x;
 88     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 89     change(1,1,n,numl[x],sum[x]);
 90     sum[y]=(sum[son[y].l]+sum[son[y].r]+a[y])%mo;
 91     change(1,1,n,numl[y],sum[y]);
 92 }
 93 int main()
 94 {
 95     //freopen("splay.in","r",stdin);
 96     //freopen("splay.out","w",stdout);
 97     scanf("%d%d",&n,&q);
 98     f[0]=1;
 99     for (int i=0;i<2000010;i++) tree[i].mul=1;
100     for (int i=1;i<=n;i++)
101     {
102         scanf("%d%d%d",&a[i],&son[i].l,&son[i].r);
103         f[i]=1;
104         fa[son[i].l]=i; fa[son[i].r]=i;
105     }
106     dfs(1);
107     build(1,1,n);
108     for (int i=1;i<=q;i++)
109     {
110         scanf("%d%d",&opt,&x);
111         if (opt==0) if (son[x].l) rrotate(x);
112         if (opt==1) if (son[x].r) lrotate(x);
113         if (opt==2)
114         {
115             ans=1;
116             mul(1,1,n,numl[x]-size[son[x].l],numl[x]+size[son[x].r]);
117             printf("%lld\n",ans);
118         }
119     }
120     return 0;
121 }

 

posted @ 2018-04-20 20:08  BEYang_Z  阅读(218)  评论(0编辑  收藏  举报