zoukankan      html  css  js  c++  java
  • CF757G Can Bash Save the Day?

    CF757G Can Bash Save the Day?

    #include<bits/stdc++.h>
    #define RG register
    #define IL inline
    #define _ 200100
    #define ycb (1<<30) 
    #define ll long long 
    using namespace std;
    
    IL int gi(){
        RG int data = 0 , m = 1; RG char ch = 0;
        while(ch != '-' && (ch<'0' || ch > '9')) ch = getchar();
        if(ch == '-'){m = 0; ch = getchar();}
        while(ch>='0' && ch<='9'){data = (data<<1) + (data<<3) + ch - '0' ;  ch = getchar();}
        return (m) ? data : -data ; 
    }
    
    int fa[_],son[_],sz[_],dep[_],dfn[_],top[_];
    struct YCB{int ls,rs; ll tag,sum;} t[120*_] ;  int n,Q,a[_],rt[_],tot; 
    struct Road{int to,next,w;}edg[2*_] ; int head[_],cnt; ll dis[_],bit[_],ans,predist[_];
    
    IL void add(int u,int v,int w){
        edg[++cnt] = (Road){v , head[u] , w} ; head[u] = cnt ;
    }
    
    void dfs1(int u,int fth,ll dist){
        fa[u] = fth; dis[u] = dist;
        son[u] = 0; sz[u] = 1;  
        for(int i = head[u]; i; i = edg[i].next){
            int v = edg[i].to;
            if(v == fth)continue;
            dfs1(v,u,dist + edg[i].w);
            if(!son[u] || sz[son[u]] < sz[v])son[u] = v;
            sz[u] = sz[u] + sz[v];
        }
    }
    void dfs2(RG int u,RG int upp){
        top[u] = upp; dfn[u] = ++cnt;
        predist[cnt] = predist[cnt-1] + dis[u] - dis[fa[u]] ;	
        if(son[u]) dfs2(son[u] ,upp) ;  else return ;	
        for(RG int i = head[u] ; i ; i = edg[i].next){
            RG int v = edg[i].to;
            if(v == fa[u] || v == son[u]) continue;		
            if(v != son[u]) dfs2(v , v) ;		
        }return ; 
    }
    
    IL void Pre(){
        n = gi(); Q = gi();
        for(RG int i = 1; i <= n; i ++) a[i] = gi() ;
        for(RG int i = 1,u,v,w; i <= n-1; i ++)
            u = gi() , v = gi() , w = gi() , add(u,v,w) , add(v,u,w) ;
        dfs1(1,0,0); cnt = 0; dfs2(1,1);
    }
    
    IL void Ins(int x,ll d){while(x<=n)bit[x] += d , x += (x&-x); }
    IL ll get(int x){RG ll ret = 0; while(x)ret += bit[x] , x -= (x&-x); return ret ; }
    
    void Build(int &o,int l,int r){
        o = ++ tot;
        t[o].tag = t[o].sum =0; if(l == r)return ; 
        RG int mid = (l + r) >> 1;
        Build(t[o].ls , l , mid) ; Build(t[o].rs , mid + 1 , r) ;
    }
    
    void Update(int &o,int l,int r,int ql,int qr){
        t[++tot] = t[o]; o = tot;
        if(ql == l && r == qr){t[o].tag++; return ; }
        t[o].sum += predist[qr] - predist[ql-1] ; 
        RG int mid = (l + r) >> 1;
        if(qr <= mid) Update(t[o].ls , l , mid , ql , qr) ;
        else if(ql  > mid) Update(t[o].rs , mid + 1, r , ql , qr) ;
        else Update(t[o].ls,l,mid,ql,mid) , Update(t[o].rs,mid+1,r,mid+1,qr) ; 
    }
    
    ll Query(int o,int l,int r,int ql,int qr){
        RG ll dt = 1ll * t[o].tag * (predist[qr]-predist[ql-1]) ;
        if(ql == l && r == qr) return t[o].sum + dt;
        RG int mid = (l + r) >> 1; 
        if(qr <= mid) return dt + Query(t[o].ls , l , mid , ql , qr) ;
        if(ql > mid) return dt + Query(t[o].rs , mid + 1 , r , ql , qr) ;
        return dt + Query(t[o].ls , l , mid , ql , mid) + Query(t[o].rs , mid + 1, r , mid + 1, qr); 
    }
    
    IL void Modify_Pre(int P,int p){
        while(top[p] ^ 1)
            Update(rt[P] , 1 , n , dfn[top[p]] , dfn[p]) , 
                p = fa[top[p]] ;
        if(p ^ 1) Update(rt[P] , 1 , n , dfn[son[1]] , dfn[p]) ;
    }
    IL ll Calc_Pre(int root,int p){
        RG ll ret = 0;
        while(top[p] ^ 1)
            ret = ret + Query(root , 1 , n , dfn[top[p]] , dfn[p]) ,
                p = fa[top[p]] ;
        if(p ^ 1) ret += Query(root , 1 , n , dfn[son[1]] , dfn[p]) ;
        return ret ;
    }
    
    int main(){
        Pre();
        Build(rt[0] , 1 , n) ;
        for(RG int i = 1; i <= n; i ++)
            rt[i] = rt[i-1] , Modify_Pre(i , a[i]) ;
        for(RG int i = 1; i <= n; i ++) Ins(i , dis[a[i]]) ; 
        RG int opt,l,r,x;
        ans = 0;
        while(Q--){
            opt = gi();
            if(opt == 2) x = gi() ;
            else l = gi() , r = gi() , x = gi() ;
            l = (ans % ycb) ^ l ;
            r = (ans % ycb) ^ r ;
            x = (ans % ycb) ^ x ;
            if(l > r) swap(l , r) ;
            if(opt == 1){
                ans = 0;
                ans += 1ll * (r-l+1) * dis[x] ;
                ans += get(r) - get(l-1) ;
                ans -= 1ll * 2 * (Calc_Pre(rt[r] , x) - Calc_Pre(rt[l-1] , x));
                printf("%lld
    " , ans) ;
            }
            else if(opt == 2){
                rt[x] = rt[x-1] ;
                Modify_Pre(x , a[x+1]) ;
                Ins(x , -dis[a[x]]); Ins(x+1 , -dis[a[x+1]]); 
                swap(a[x] , a[x+1]) ;
                Ins(x , dis[a[x]]) ; Ins(x+1 , dis[a[x+1]]) ; 
            }
        }return 0;
    }
    
    
  • 相关阅读:
    面试官:Redis 有哪些拓展方案?
    面试官:为什么要合并 HTTP 请求?
    Java 调用第三方接口,实战来了!
    Java 如何模拟真正的并发请求?
    如何搭建一台永久运行的个人服务器?试试这个黑科技!
    vs2005 sp1 出来啦!!
    2007年第一帖
    xp pro sp2支持多个用户同时终端连接
    msn中实现 "添加一个活动或游戏邀请"
    softether
  • 原文地址:https://www.cnblogs.com/Guess2/p/8708434.html
Copyright © 2011-2022 走看看