• BZOJ_3786_星系探索_splay维护出栈入栈序


    BZOJ_3786_星系探索_splay维护出栈入栈序

    Description

    物理学家小C的研究正遇到某个瓶颈。

    他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球。主星球没有依赖星球。

    我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c.

    对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的。并且从星球a出发只能直接到达它的依赖星球b.

    每个星球i都有一个能量系数wi.小C想进行若干次实验,第i次实验,他将从飞船上向星球di发射一个初始能量为0的能量收集器,能量收集器会从星球di开始前往主星球,并收集沿途每个星球的部分能量,收集能量的多少等于这个星球的能量系数。

    但是星系的构成并不是一成不变的,某些时刻,星系可能由于某些复杂的原因发生变化。

    有些时刻,某个星球能量激发,将使得所有依赖于它的星球以及他自己的能量系数均增加一个定值。还有可能在某些时刻,某个星球的依赖星球会发生变化,但变化后依然满足依赖关系是无环的。

    现在小C已经测定了时刻0时每个星球的能量系数,以及每个星球(除了主星球之外)的依赖星球。接下来的m个时刻,每个时刻都会发生一些事件。其中小C可能会进行若干次实验,对于他的每一次实验,请你告诉他这一次实验能量收集器的最终能量是多少。

    Input

    第一行一个整数n,表示星系的星球数。

    接下来n-1行每行一个整数,分别表示星球2-n的依赖星球编号。

    接下来一行n个整数,表示每个星球在时刻0时的初始能量系数wi.

    接下来一行一个整数m,表示事件的总数。

    事件分为以下三种类型。

    (1)"Q di"表示小C要开始一次实验,收集器的初始位置在星球di.

    (2)"C xi yi"表示星球xi的依赖星球变为了星球yi.

    (3)"F pi qi"表示星球pi能量激发,常数为qi.

    Output

    对于每一个事件类型为Q的事件,输出一行一个整数,表示此次实验的收集器最终能量。

     

    Sample Input

    3
    1
    1
    4 5 7
    5
    Q 2
    F 1 3
    Q 2
    C 2 3
    Q 2

    Sample Output

    9
    15
    25

    HINT

    n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000.保证操作合法。注意w_i>=0


    考虑用splay维护出栈入栈序,这样我们求前缀和就是点到根路径的权值和了。

    换根操作也比较容易实现,因为子树对应着一段区间,直接移动子树即可。

    就是子树加不太好做,因为是加点权,不包含系数。

    于是我们再维护出有多少个正数有多少个负数即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    #define N 200050
    #define ls ch[p][0]
    #define rs ch[p][1]
    #define get(x) (ch[f[x]][1]==x)
    int head[N],to[N],nxt[N],cnt,ch[N][2],f[N],rt,n,m,tot,dfn[N],siz[N],son[N];
    int zc[N],fc[N],a[N],type[N],val[N],w[N],fa[N];
    ll sum[N];
    int del[N];
    char pbuf[100000],*pp=pbuf;
    __attribute__((optimize("-O3")))void push(const char ch) {
        if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
        *pp++=ch;
    }
    __attribute__((optimize("-O3")))void write(ll x) {
        static int sta[50];
        int top=0;
        do{sta[++top]=x%10,x/=10;}while(x);
        while(top) push(sta[top--]+'0');
        push('
    ');
    }
    __attribute__((optimize("-O3")))inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    __attribute__((optimize("-O3")))int rd() {
        int x=0; char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    __attribute__((optimize("-O3")))char rc() {
        char s=nc();
        while(s!='Q'&&s!='C'&&s!='F') s=nc();
        return s;
    }
    __attribute__((optimize("-O3")))void give(int p,int v) {
        val[p]+=v; del[p]+=v; sum[p]+=1ll*(zc[p]-fc[p])*v;
    }
    __attribute__((optimize("-O3")))void pushup(int p) {
        if(!p) return ;
        siz[p]=1;
        zc[p]=fc[p]=0;
        if(type[p]==1) zc[p]=1;
        else if(type[p]==-1) fc[p]=1;
        sum[p]=val[p]*type[p];
        siz[p]+=siz[ls],sum[p]+=sum[ls],zc[p]+=zc[ls],fc[p]+=fc[ls];
        siz[p]+=siz[rs],sum[p]+=sum[rs],zc[p]+=zc[rs],fc[p]+=fc[rs];
    }
    __attribute__((optimize("-O3")))void pushdown(int p) {
        if(del[p]) {
            if(ls) give(ls,del[p]);
            if(rs) give(rs,del[p]);
            del[p]=0;
        }
    }
    __attribute__((optimize("-O3")))void rotate(int x) {
        int y=f[x],z=f[y],k=get(x);
        ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
        ch[x][!k]=y; f[y]=x; f[x]=z;
        if(z) ch[z][ch[z][1]==y]=x;
        if(rt==y) rt=x;
        pushup(y); pushup(x);
    }
    __attribute__((optimize("-O3")))void update(int p,int y) {
        if(f[p]!=y) update(f[p],y);
        pushdown(p);
    }
    __attribute__((optimize("-O3")))void splay(int x,int y) {
        update(x,y);
        for(int d;(d=f[x])!=y;rotate(x))
            if(f[d]!=y)
                rotate(get(x)==get(d)?d:x);
    }
    __attribute__((optimize("-O3")))inline void add(int u,int v) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
    }
    __attribute__((optimize("-O3")))void dfs(int x) {
        int i;a[++tot]=x; type[tot+1]=1; dfn[x]=tot+1; val[tot+1]=w[x];
        for(i=head[x];i;i=nxt[i]) {
            f[to[i]]=x;
            dfs(to[i]);
        }
        a[++tot]=x; type[tot+1]=-1; son[x]=tot+1; val[tot+1]=w[x];
    }
    __attribute__((optimize("-O3")))void build(int fa,int l,int r) {
        if(l>r) return ;
        int mid=(l+r)>>1;
        f[mid]=fa;
        ch[fa][mid>fa]=mid;
        build(mid,l,mid-1);
        build(mid,mid+1,r);
        pushup(mid);
    }
    __attribute__((optimize("-O3")))int pre() {
        int p=ch[rt][0];
        for(;rs;p=rs) pushdown(p);
        return p;
    }
    __attribute__((optimize("-O3")))int suc() {
        int p=ch[rt][1];
        for(;ls;p=ls) pushdown(p);
        return p;
    }
    __attribute__((optimize("-O3")))void huan(int x,int y) {
        splay(dfn[x],0); int p2=pre();
        splay(son[x],0); int p4=suc();
        splay(p2,0); splay(p4,p2);
        int p5=ch[p4][0]; f[p5]=0; ch[p4][0]=0;
        pushup(p4); pushup(p2);
        int p6=dfn[y];
        splay(p6,0); int p7=suc();
        splay(p7,p6);
        ch[p7][0]=p5; f[p5]=p7;
        pushup(p5); pushup(p7); pushup(p6);
    }
    __attribute__((optimize("-O3")))int find(int x) {
        int p=rt;
        while(1) {
            pushdown(p);
            if(x<=siz[ls]) p=ls;
            else {
                x-=siz[ls]+1;
                if(!x) return p;
                p=rs;
            }
        }
    }
    __attribute__((optimize("-O3")))void print() {
        int i,p;
        for(i=1;i<=tot+2;i++) {
            p=find(i);
            printf("i=%d,p=%d,val[p]=%d,f[p]=%d,zc[p]=%d,fc[p]=%d
    ",i,p,val[p],f[p],zc[p],fc[p]);
        }
    }
    __attribute__((optimize("-O3")))int main() {
        n=rd();
        register int i,x,y,p;
        for(i=2;i<=n;i++) {
            x=rd();
            add(x,i);
        }
        for(i=1;i<=n;i++) w[i]=rd();
        dfs(1);
        build(0,1,tot+2);
        rt=(tot+3)>>1;
        m=rd();
        char opt;
        while(m--) {
            opt=rc(); x=rd();
            if(opt=='Q') {
                x=dfn[x]; 
                // splay(x,0); p=suc();
                // splay(1,0); splay(p,1);
                splay(1,0);
                splay(x,1); 
                for(p=ch[x][1];ls;p=ls);
                splay(p,1);
                write(sum[ls]);
            }else if(opt=='C') {
                y=rd();
                // scanf("%d",&y);
                if(fa[x]!=y) huan(x,y),fa[x]=y;
            }else {
                y=rd();
                // scanf("%d",&y);
                int q=dfn[x]; 
                splay(q,0); p=pre();
                int t1=p;
                q=son[x];
                splay(q,0); p=suc();
                splay(t1,0); splay(p,t1);
                give(ls,y);
            }
        }
        fwrite(pbuf,1,pp-pbuf,stdout);
    }
    
  • 相关阅读:
    谷歌地图嵌入配置及代码生成器
    Easyui几种布局方式的使用
    9款超酷的jQuery/CSS3插件
    8款功能强大的最新HTML5特效实例
    《大话操作系统——做坚实的project实践派》(2)
    1、libgdx简单介绍
    自己定义Android Dialog
    纪念2014 TI DSP大奖赛
    LeetCode 96:Unique Binary Search Trees
    Chromium网页输入事件捕捉和手势检測过程分析
  • 原文地址:https://www.cnblogs.com/suika/p/9240156.html
Copyright © 2020-2023  润新知