• suoi22 WRX知识树(dfs序)


    把一条路径拆成到根的四个链(两端点、lca和fa[lca]),然后给dfs序中链的端点做单点修改、区间查询它的子树和再加上它原来的权值就可以了

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define lowb(x) ((x)&(-(x)))
      4 #define REP(i,n0,n) for(i=n0;i<=n;i++)
      5 #define PER(i,n0,n) for(i=n;i>=n0;i--)
      6 #define MAX(a,b) ((a>b)?a:b)
      7 #define MIN(a,b) ((a<b)?a:b)
      8 #define CLR(a,x) memset(a,x,sizeof(a))
      9 #define rei register int
     10 using namespace std;
     11 typedef long long ll;
     12 const int maxn=1e6+10;
     13 
     14 inline ll rd(){
     15     ll x=0;char c=getchar();int neg=1;
     16     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     17     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     18     return x*neg;
     19 }
     20 
     21 int N,M;
     22 int eg[maxn*2][2],egh[maxn],ect;
     23 int v[maxn],fa[maxn],bfa[maxn];
     24 int lq[maxn*2][2],lqh[maxn],lca[maxn][2];
     25 int dfn[maxn][2],tot;
     26 int stk[maxn][2],sh;
     27 ll tr[maxn];
     28 int que[maxn];
     29 bool vis[maxn];
     30 
     31 inline void adeg(int a,int b){
     32     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
     33 }
     34 
     35 int getf(int x){return x==bfa[x]?x:bfa[x]=getf(bfa[x]);}
     36 
     37 inline void add(int x,ll y){
     38     for(;x>0&&x<=N;x+=lowb(x)) tr[x]+=y;
     39 }
     40 inline ll query(int x){
     41     ll re=0;for(;x>0;x-=lowb(x)) re+=tr[x];return re;
     42 }
     43 
     44 void dfs(){
     45     stk[sh=1][0]=1;stk[1][1]=egh[1];
     46     dfn[1][0]=tot=1;
     47     while(sh){
     48         int x=stk[sh][0],i=stk[sh][1],b=eg[i][0];
     49         vis[x]=1;
     50         if(!i){
     51             for(int j=lqh[x];j;j=lq[j][1]){
     52                 int c=lq[j][0];
     53                 if(vis[c]) lca[j>>1][0]=getf(c);
     54             }
     55             bfa[getf(x)]=fa[x];
     56             dfn[x][1]=tot;
     57             sh--;continue;
     58         }
     59         stk[sh][1]=eg[i][1];
     60         if(!vis[b]){
     61             fa[b]=x;stk[++sh][0]=b,stk[sh][1]=egh[b];
     62             dfn[b][0]=++tot;
     63         }
     64         
     65     }
     66 }
     67 
     68 int main(){
     69     //freopen(".in","r",stdin);
     70     rei i;
     71     N=rd(),M=rd();
     72     for(i=1;i<=N;i++) v[i]=rd();
     73     for(i=1;i<N;i++){
     74         int a=rd(),b=rd();
     75         adeg(a,b);adeg(b,a);
     76     }for(i=1;i<=N;i++) bfa[i]=i;
     77     for(i=1;i<=M;i++){
     78         int a=rd(),b=rd();
     79         if(!a){
     80             que[i]=b;
     81         }else{
     82             int c=rd(),d=rd();
     83             lca[i][1]=d;
     84             lq[i<<1][0]=b;lq[i<<1][1]=lqh[c];lqh[c]=i<<1;
     85             lq[i<<1|1][0]=c;lq[i<<1|1][1]=lqh[b];lqh[b]=i<<1|1;
     86         }
     87     }
     88     dfs();
     89     for(i=1;i<=M;i++){
     90         if(lca[i][0]){
     91             // printf("!%d %d %d
    ",lca[i][0],lq[i<<1][0],lq[i<<1|1][0]);
     92             add(dfn[lca[i][0]][0],-lca[i][1]);
     93             if(fa[lca[i][0]]) add(dfn[fa[lca[i][0]]][0],-lca[i][1]);
     94             add(dfn[lq[i<<1][0]][0],lca[i][1]);
     95             add(dfn[lq[i<<1|1][0]][0],lca[i][1]);
     96             // cout<<"mmm"<<endl;
     97         }else{
     98             printf("%lld
    ",v[que[i]]+query(dfn[que[i]][1])-query(dfn[que[i]][0]-1));
     99         }
    100         
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    Valid Number
    ZigZag Conversion
    KMP
    [OJ#40]后宫佳丽
    [OJ#39]左手右手
    [COJ0968]WZJ的数据结构(负三十二)
    [COJ0970]WZJ的数据结构(负三十)
    [BZOJ2815][ZJOI2012]灾难
    [BZOJ1923][Sdoi2010]外星千足虫
    [BZOJ4034][HAOI2015]树上操作
  • 原文地址:https://www.cnblogs.com/Ressed/p/9735525.html
Copyright © 2020-2023  润新知