BZOJ 3786: 星系探索 ETT

Code: 

#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, 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\n", 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\n",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\n", 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;    
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值