• BZOJ 3786: 星系探索 ETT


    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的事件,输出一行一个整数,表示此次实验的收集器最终能量。

    这个应该是伪 $ETT$,不知道真正的 $ETT$ 该咋写. 

    开始卡了半天常数,本地 $25s$,交上去却一顿 T,后来改用结构体存变量就跑的飞快. 

    以后写数据结构就都用结构体存了 

    #include <cstdio>
    #include <algorithm> E
    #define N 200005 
    #define ll long long             
    #define lson t[x].ch[0] 
    #define rson t[x].ch[1]   
    #define setIO(s) freopen(s".in", "r", stdin) 
    using namespace std;              
    int edges, tim, root = 0, top;   
    int sta[N], hd[N], to[N], nex[N], L[N], R[N], euler[N], val[N];          
    inline void addedge(int u, int v) 
    {
        nex[++edges] = hd[u], hd[u] = edges, to[edges] = v;   
    }  
    struct Stack 
    { 
        int x, i;         
        Stack(int x = 0, int i = 0) : x(x), i(i) {}    
    }A[N]; 
    struct Node  
    { 
        int siz, d, ch[2], f; 
        ll sum, val, lazy;           
    }t[N];                     
    inline int get(int x) 
    {
        return t[t[x].f].ch[1] == x;   
    } 
    inline void pushup(int x) 
    {
        t[x].siz = t[lson].siz + t[rson].siz + t[x].d;   
        t[x].sum = t[lson].sum + t[rson].sum + t[x].val; 
    }
    inline void mark(int x, ll v) 
    {
        t[x].val += 1ll * t[x].d * v;                  
        t[x].sum += 1ll * t[x].siz * v;    
        t[x].lazy += v;         
    }
    inline void pushdown(int x) 
    { 
        if(t[x].lazy) 
        {
            if(lson) mark(lson, t[x].lazy); 
            if(rson) mark(rson, t[x].lazy); 
            t[x].lazy = 0;      
        }
    }
    inline void rotate(int x) 
    {
        int old = t[x].f, fold = t[old].f, which = get(x);    
        t[old].ch[which] = t[x].ch[which ^ 1], t[t[old].ch[which]].f = old;           
        t[x].ch[which ^ 1] = old, t[old].f = x, t[x].f = fold;  
        if(fold) t[fold].ch[t[fold].ch[1] == old] = x;    
        pushup(old), pushup(x); 
    } 
    inline void splay(int x, int &tar) 
    {
        int u = t[tar].f, v = 0; 
        for(int g = x ; g ; sta[++v] = g, g = t[g].f);          
        for(int i = v ; i >= 1; --i) pushdown(sta[i]);    
        for(int fa; (fa = t[x].f) ^ u; rotate(x)) 
            if(t[fa].f ^ u) 
                rotate(get(fa) == get(x) ? fa: x);    
        tar = x; 
    }   
    void solve() 
    { 
        top = 0;         
        A[++ top] = Stack(1, hd[1]), L[1] = ++tim, t[tim].d = 1, t[tim].val = (ll) val[1];         
        for( ; top ; ) 
        {     
            Stack u = A[top];                  
            if(u.i) 
            {    
                A[top].i = nex[A[top].i];      
                A[++ top] = Stack(to[u.i], hd[to[u.i]]);  
                L[to[u.i]] = ++tim; 
                t[tim].d = 1, t[tim].val = (ll) val[to[u.i]];                
            }
            else 
            {           
                R[u.x] = ++tim;    
                t[tim].d = -1, t[tim].val = (ll) -val[u.x];          
                -- top;     
            }    
        }
    }
    int build(int l, int r, int ff) 
    {
        int mid = (l + r) >> 1;           
        t[mid].f = ff;      
        if(mid > l) t[mid].ch[0] = build(l, mid - 1, mid);   
        if(r > mid) t[mid].ch[1] = build(mid + 1, r, mid);        
        if(mid == 1) t[mid].ch[0] = tim + 1, t[tim + 1].f = mid;       
        if(mid == tim) t[mid].ch[1] = tim + 2, t[tim + 2].f = mid;     
        pushup(mid);              
        return mid;       
    }  
    int pre(int x) 
    {       
        int g = root;  
        splay(x, root);   
        for(x = lson; rson ; pushdown(x), x = rson); 
        splay(g, root);    
        return x;    
    } 
    int nxt(int x) 
    {
        int g = root; 
        splay(x, root);     
        for(x = rson; lson ; pushdown(x), x = lson);    
        splay(g, root); 
        return x;         
    }
    int main() 
    {
        // setIO("input");  
        int n, m, i, j, x, y; 
        scanf("%d", &n); 
        for(i = 2; i <= n ; ++i) scanf("%d", &x), addedge(x, i);        
        for(i = 1; i <= n ; ++i) scanf("%d", &val[i]);   
        solve(),  root = build(1, tim , 0);                              
        scanf("%d", &m); 
        for(int cas = 1; cas <= m; ++cas) 
        {
            char str[4];  
            scanf("%s", str);    
            if(str[0] == 'Q') 
            {
                scanf("%d", &x), splay(L[x], root), printf("%lld
    ", t[root].sum - t[t[root].ch[1]].sum);          
            }
            if(str[0] == 'C') 
            {        
                scanf("%d%d", &x, &y);        
                int l = pre(L[x]), r = nxt(R[x]), key, k;       
                splay(l, root), splay(r, t[root].ch[1]), key = t[t[root].ch[1]].ch[0]; 
                t[key].f = t[t[root].ch[1]].ch[0] = 0, pushup(t[root].ch[1]), pushup(root);     
                splay(L[y], root), splay(nxt(L[y]), t[root].ch[1]);      
                t[t[root].ch[1]].ch[0] = key, t[key].f = t[root].ch[1], pushup(t[root].ch[1]), pushup(root);     
            }    
            if(str[0] == 'F') 
            {
                scanf("%d%d", &x, &y);             
                splay(pre(L[x]), root), splay(nxt(R[x]), t[root].ch[1]);      
                int key = t[t[root].ch[1]].ch[0];    
                mark(key, 1ll * y);         
            }            
        }                 
        return 0;    
    }
    

      

    递归: 

    #include <cstdio>
    #include <algorithm> 
    #define N 200005 
    #define ll long long             
    #define lson t[x].ch[0] 
    #define rson t[x].ch[1]   
    #define setIO(s) freopen(s".in", "r", stdin) 
    using namespace std;              
    int edges, tim, root = 0;   
    int sta[N], hd[N], to[N], nex[N], L[N], R[N], euler[N], val[N];        
    inline void addedge(int u, int v) 
    {
        nex[++edges] = hd[u], hd[u] = edges, to[edges] = v;   
    }  
    struct Node  
    { 
        int siz, d, ch[2], f; 
        ll sum, val, lazy;           
    }t[N];                     
    inline int get(int x) 
    {
        return t[t[x].f].ch[1] == x;   
    } 
    inline void pushup(int x) 
    {
        t[x].siz = t[lson].siz + t[rson].siz + t[x].d;   
        t[x].sum = t[lson].sum + t[rson].sum + t[x].val; 
    }
    inline void mark(int x, ll v) 
    {
        t[x].val += 1ll * t[x].d * v;                  
        t[x].sum += 1ll * t[x].siz * v;    
        t[x].lazy += v;         
    }
    inline void pushdown(int x) 
    { 
        if(t[x].lazy) 
        {
            if(lson) mark(lson, t[x].lazy); 
            if(rson) mark(rson, t[x].lazy); 
            t[x].lazy = 0;      
        }
    }
    inline void rotate(int x) 
    {
        int old = t[x].f, fold = t[old].f, which = get(x);    
        t[old].ch[which] = t[x].ch[which ^ 1], t[t[old].ch[which]].f = old;           
        t[x].ch[which ^ 1] = old, t[old].f = x, t[x].f = fold;  
        if(fold) t[fold].ch[t[fold].ch[1] == old] = x;    
        pushup(old), pushup(x); 
    } 
    inline void splay(int x, int &tar) 
    {
        int u = t[tar].f, v = 0; 
        for(int g = x ; g ; sta[++v] = g, g = t[g].f);          
        for(int i = v ; i >= 1; --i) pushdown(sta[i]);    
        for(int fa; (fa = t[x].f) ^ u; rotate(x)) 
            if(t[fa].f ^ u) 
                rotate(get(fa) == get(x) ? fa: x);    
        tar = x; 
    }
    void dfs(int u) 
    {
        L[u] = ++tim;       
        t[tim].d = 1, t[tim].val = (ll)val[u];      
        for(int i = hd[u] ; i ; i = nex[i]) dfs(to[i]);    
        R[u] = ++tim;     
        t[tim].d = -1, t[tim].val = (ll)-val[u];          
    }
    int build(int l, int r, int ff) 
    {
        int mid = (l + r) >> 1;           
        t[mid].f = ff;      
        if(mid > l) t[mid].ch[0] = build(l, mid - 1, mid);   
        if(r > mid) t[mid].ch[1] = build(mid + 1, r, mid);        
        if(mid == 1) t[mid].ch[0] = tim + 1, t[tim + 1].f = mid;       
        if(mid == tim) t[mid].ch[1] = tim + 2, t[tim + 2].f = mid;     
        pushup(mid);   
        // printf("%d %d %d
    ",mid, t[mid].ch[0], t[mid].ch[1]);            
        return mid;       
    }  
    int pre(int x) 
    {       
        int g = root;  
        splay(x, root);   
        for(x = lson; rson ; pushdown(x), x = rson); 
        splay(g, root);    
        return x;    
    } 
    int nxt(int x) 
    {
        int g = root; 
        splay(x, root);     
        for(x = rson; lson ; pushdown(x), x = lson);    
        splay(g, root); 
        return x;         
    }
    int main() 
    {
        // setIO("input");  
        int n, m, i, j, x, y; 
        scanf("%d", &n); 
        for(i = 2; i <= n ; ++i) scanf("%d", &x), addedge(x, i);        
        for(i = 1; i <= n ; ++i) scanf("%d", &val[i]);   
        dfs(1), root = build(1, tim , 0);                              
        scanf("%d", &m); 
        for(int cas = 1; cas <= m; ++cas) 
        {
            char str[4];  
            scanf("%s", str);    
            if(str[0] == 'Q') 
            {
                scanf("%d", &x), splay(L[x], root), printf("%lld
    ", t[root].sum - t[t[root].ch[1]].sum);          
            }
            if(str[0] == 'C') 
            {        
                scanf("%d%d", &x, &y);        
                int l = pre(L[x]), r = nxt(R[x]), key, k;       
                splay(l, root), splay(r, t[root].ch[1]), key = t[t[root].ch[1]].ch[0]; 
                t[key].f = t[t[root].ch[1]].ch[0] = 0, pushup(t[root].ch[1]), pushup(root);     
                splay(L[y], root), splay(nxt(L[y]), t[root].ch[1]);      
                t[t[root].ch[1]].ch[0] = key, t[key].f = t[root].ch[1], pushup(t[root].ch[1]), pushup(root);     
            }    
            if(str[0] == 'F') 
            {
                scanf("%d%d", &x, &y);             
                splay(pre(L[x]), root), splay(nxt(R[x]), t[root].ch[1]);      
                int key = t[t[root].ch[1]].ch[0];    
                mark(key, 1ll * y);         
            }            
        }                 
        return 0;    
    }
    

      

  • 相关阅读:
    DataSingleton单例
    iOS平台XML解析类库对比和安装说明
    ASIHTTPRequest类库简介和使用说明
    IOS开发之格式化日期时间
    iOS多线程编程之NSThread的使用
    Django的Xadmin后台集成富文本Ueditor
    Django DEBUG=False后静态文件加载失败
    Python多进程
    linux平台虚拟环境依赖安装
    SQLite基础使用
  • 原文地址:https://www.cnblogs.com/guangheli/p/11332181.html
Copyright © 2020-2023  润新知