zoukankan      html  css  js  c++  java
  • 树剖

    #include<bits/stdc++.h>
    
    using namespace std ;
    
    const int MAXN = 100010;
    int a[MAXN],dt[MAXN],n,m,r,p,cnt;
    int dep[MAXN],fa[MAXN],son[MAXN],siz[MAXN],topc[MAXN],ID[MAXN],res;
    
    struct Edge{
        int to,nxt;
    }edge[MAXN];//tree's Edge -> MAXN-1
    int head[MAXN],ectr;
    void addedge(int from,int to){
        ectr++;
        edge[ectr].to = to;
        edge[ectr].nxt = head[from];
        head[from] = ectr;
    }
    
    struct Tree{
        int l ,r ,dat ,lazy ;
    }tree[MAXN<<2];
    
    void build(int q,int l,int r){
        tree[q].l=l,tree[q].r=r;
        if(l == r){
            tree[q].dat = dt[l];
            if(tree[q].dat > p) tree[q].dat%=p;
            return ;
        }
        int mid = (l+r)/2;
        build(q<<1,l,mid);
        build(q<<1|1,mid+1,r);
        tree[q].dat = tree[q<<1].dat + tree[q<<1|1].dat;
        return ;
    }
        
    void change (int q, int l, int r, int d)//?????? 
    {
        if(tree[q].l==l && tree[q].r==r)
        {
            tree[q].dat+=d*(r-l+1);
            tree[q].lazy+=d;
            return ;
        }
        int mid = ( tree[q].l + tree[q].r ) /2;//??????
        if(tree[q].lazy!=0)
        {
            change ( q<<1, tree[q].l, mid, tree[q].lazy);
            change ( q<<1|1, mid+1, tree[q].r, tree[q].lazy);
            tree[q].lazy=0;
        }
        if(r<=mid) change ( q*2, l, r, d);
        else if(l>mid) change( q*2+1, l, r, d);
        else
        {
            change ( q*2, l, mid, d) ;
            change ( q*2+1, mid+1, r, d) ;
        }
        tree[q].dat = tree[q*2].dat + tree[q*2+1].dat;
        return; 
    }
        
    int query(int q, int l, int r)
    {
        int mid = ( tree[q].l + tree[q].r ) / 2;
        if(tree[q].l==l && tree[q].r==r) return tree[q].dat;
        if(tree[q].lazy!=0)
        {
            change ( q<<1, tree[q].l, mid, tree[q].lazy);
            change ( q<<1|1, mid+1, tree[q].r, tree[q].lazy);
            tree[q].lazy=0;
        }
        if(r<=mid) return query(q<<1, l, r);
        else if(l>mid) return query(q<<1|1, l, r);
        else return ( query(q<<1, l, mid) + query(q<<1|1, mid+1, r) );
    }
    
    void BRONYA_IS_THE_BEST(int x,int y,int deep){//x -> now , y -> father
        siz[x] = 1;
        dep[x] = deep;
        fa[x] = y;
        int maxson = -1;
        for(register int i = head[x];i;i = edge[i].nxt){
            int v = edge[i].to;
            if (v==y) continue;
            BRONYA_IS_THE_BEST(v,x,deep+1);
            siz[x] += siz[v];
            if(siz[v] > maxson) {
                son[x] = v;
                maxson = siz[v];
             }
        }
        return ;
    }
    
    void TERISHA_IS_THE_CUTEST(int x ,int ct){//ct == chain_top
        ID[x] = ++cnt ;
        dt[cnt] = a[x];
        topc[x] = ct;
        if(!son[x]) return ;
        TERISHA_IS_THE_CUTEST(son[x],ct);
        for(register int i = head[x];i ;i = edge[i].nxt){
            int v = edge[i].to;
            if(v == fa[x] || v == son[x]) continue ;
            TERISHA_IS_THE_CUTEST(v,v);
        }
        return ;
    }
    
    int I_WANT_YAYI_S_XX(int x,int y){//?????????? 
        int ans = 0;
        while (topc[x] != topc[y]){//??topc???????????????ID[] 
            if(dep[x] < dep[y]) swap(x,y);//?????????? 
            res = query(1,ID[topc[x]],ID[x]);
            ans += res;
            ans %= p;
            x = fa[topc[x]];//???? 
        }
        if(dep[x] > dep[y]) swap(x,y);
        res = query(1,ID[x],ID[y]);
        ans+=res;
        ans%=p;
        return ans ;//? 
    }
    
    int CSY_IS_PSYCHO(int x){
        res = query(1,ID[x],ID[x]+siz[x]-1);
        return res ;
    }
    
    int main(){
        scanf("%d%d%d%d",&n,&m,&r,&p);//r -> root ,p -> mod
        for(register int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(register int i=1,x,y;i<n;i++){
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        BRONYA_IS_THE_BEST(r,0,1);//fa[r] = 0
        TERISHA_IS_THE_CUTEST(r,r);
        for(register int i=1,flag;i<=m;i++){
            scanf("%d",&flag);
            if(flag == 1){
                int tra1,tra2,tra3;
                scanf("%d%d%d",&tra1,&tra2,&tra3);
                change(1,ID[tra1],ID[tra2],tra3);
            }
            if(flag == 2){
                int tra1,tra2;
                scanf("%d%d",&tra1,&tra2);
                printf("%d",I_WANT_YAYI_S_XX(tra1,tra2));
            }
            if(flag == 3){
                int tra1,tra2;
                scanf("%d%d",&tra1,&tra2);
                change(1,ID[tra1],ID[tra1]+siz[tra1]-1,tra2);
            }
            if(flag == 4){
                int tra1;
                scanf("%d",&tra1);
                printf("%d",CSY_IS_PSYCHO(tra1));
            }
        }
    //    for(int i=1;i<=n;i++){
    //        cout<<"NODE "<<i<<": siz="<<siz[i]<<",father="<<fa[i]<<",deep="<<dep[i]<<",bigson="<<son[i]<<endl;
    //    }
    //    for(int i=1;i<=n;i++){
    //        cout<<"NODE"<<i<<": newID="<<ID[i]<<",data="<<dt[ID[i]]<<endl;//NOTICE : dt[ID[i]]
    //    }
        return 0;
    }
  • 相关阅读:
    android 中文 api (43) —— Chronometer
    SVN客户端清除密码
    Android 中文 API (35) —— ImageSwitcher
    Android 中文API (46) —— SimpleAdapter
    Android 中文 API (28) —— CheckedTextView
    Android 中文 API (36) —— Toast
    Android 中文 API (29) —— CompoundButton
    android 中文 API (41) —— RatingBar.OnRatingBarChangeListener
    Android 中文 API (30) —— CompoundButton.OnCheckedChangeListener
    Android 中文 API (24) —— MultiAutoCompleteTextView.CommaTokenizer
  • 原文地址:https://www.cnblogs.com/SINXIII/p/10974500.html
Copyright © 2011-2022 走看看