• [bzoj2836] 魔法树


      俩操作:增加路径上的点的权值。查询子树的权值和。

      想了想似乎只能树链剖分了。。好久没写链剖+数据结构了TAT

      一开始没开LL炸了一发(明明有想到的。。我果然是傻逼= =

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxn=100233;
      8 struct zs{
      9     int too,pre;
     10 }e[maxn<<1];int tot,last[maxn];
     11 int lc[maxn<<1],rc[maxn<<1],tt;
     12 ll sm[maxn<<1],tag[maxn<<1];
     13 int dfn[maxn],sz[maxn],fa[maxn],top[maxn],dep[maxn],tim;
     14 int i,j,k,n,m,x,y,lca,v;
     15 
     16 int ra;char rx;
     17 inline int read(){
     18     rx=getchar(),ra=0;
     19     while(rx<'0'||rx>'9')rx=getchar();
     20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     21 }
     22 
     23 
     24 inline void dfs1(int x){
     25     sz[x]=1,dep[x]=dep[fa[x]]+1;
     26     for(int i=last[x];i;i=e[i].pre)
     27         dfs1(e[i].too),sz[x]+=sz[e[i].too];
     28 }
     29 inline void dfs2(int x,int chain){
     30     top[x]=chain,dfn[x]=++tim;int i,mx=0;
     31     for(i=last[x];i;i=e[i].pre)if(sz[e[i].too]>sz[mx])mx=e[i].too;
     32     if(!mx)return;
     33     dfs2(mx,chain);
     34     for(i=last[x];i;i=e[i].pre)if(e[i].too!=mx)dfs2(e[i].too,e[i].too);
     35 }
     36 inline int getlca(int a,int b){
     37     while(top[a]!=top[b]){
     38         if(dep[top[a]]<dep[top[b]])swap(a,b);
     39         a=fa[top[a]];
     40     }
     41     return dep[a]<dep[b]?a:b;
     42 }
     43 
     44 
     45 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;}
     46 
     47 inline void pushdown(int x,int a,int b,int mid,int lc,int rc){
     48     tag[lc]+=tag[x],tag[rc]+=tag[x],sm[lc]+=tag[x]*(mid-a+1),sm[rc]+=tag[x]*(b-mid);
     49     tag[x]=0;
     50 }
     51 #define upd(x)  sm[x]=sm[lc[x]]+sm[rc[x]];
     52 inline void add(int x,int a,int b,int l,int r,int v){
     53 //    printf("add:%d %d %d    %d--%d %d
    ",x,a,b,l,r,v);
     54     if(l<=a&&r>=b){tag[x]+=v,sm[x]+=(ll)(b-a+1)*v;/*,printf("! %d
    ",sm[x]);*/return;}
     55     int mid=(a+b)>>1;
     56     if(tag[x])pushdown(x,a,b,mid,lc[x],rc[x]);
     57     if(l<=mid)add(lc[x],a,mid,l,r,v);
     58     if(r>mid) add(rc[x],mid+1,b,l,r,v);
     59     upd(x);//printf("  %d--%d  %d   %d %d
    ",a,b,sm[x],sm[lc[x]],sm[rc[x]]);
     60 }
     61 inline ll query(int x,int a,int b,int l,int r){
     62     if(l<=a&&r>=b)return sm[x];
     63     int mid=(a+b)>>1;
     64     if(tag[x])pushdown(x,a,b,mid,lc[x],rc[x]);
     65     if(r<=mid)return query(lc[x],a,mid,l,r);else
     66     if(l>mid)return query(rc[x],mid+1,b,l,r);else
     67         return query(lc[x],a,mid,l,r)+query(rc[x],mid+1,b,l,r);
     68 }
     69 inline void build(int a,int b){
     70     tt++;
     71     if(a==b)return;
     72     int mid=(a+b)>>1,x=tt;
     73     lc[x]=tt+1,build(a,mid),rc[x]=tt+1,build(mid+1,b);
     74 }
     75 
     76 
     77 inline void ADD(int x,int y,int v){
     78     while(top[x]!=top[y]){
     79         add(1,1,n,dfn[top[x]],dfn[x],v);
     80         x=fa[top[x]];
     81     }
     82     add(1,1,n,dfn[y],dfn[x],v);
     83 }
     84 /*inline ll QUERY(int x,int y){
     85     ll sum=0;
     86     while(top[x]!=top[y]){
     87         sum+=query(1,1,n,dfn[top[x]],dfn[x]);
     88         x=fa[top[x]];
     89     }
     90     return sum+query(1,1,n,dfn[y],dfn[x]);
     91 }*/
     92 
     93 
     94 int main(){
     95     n=read();
     96     for(i=1;i<n;i++)x=read()+1,y=read()+1,fa[y]=x,insert(x,y);
     97     dfs1(1),dfs2(1,1);
     98     build(1,n);char id;
     99     for(m=read();m;m--){
    100         for(id=getchar();id<'A'||id>'Z';id=getchar());
    101         if(id=='A'){
    102             x=read()+1,y=read()+1,v=read(),
    103             lca=getlca(x,y);//printf("   %d %d  lca:%d
    ",x,y,lca);
    104             ADD(x,lca,v),ADD(y,lca,v),add(1,1,n,dfn[lca],dfn[lca],-v);
    105         }else{
    106             x=read()+1;
    107             //ll sum=QUERY(x,lca)+QUERY(y,lca)-query(1,1,n,dfn[lca],dfn[lca]);
    108             ll sum=query(1,1,n,dfn[x],dfn[x]+sz[x]-1);
    109             printf("%lld
    ",sum);
    110         }
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    Python有哪些华而不实的技巧?
    json:dumps/loads & pickl
    json模块与第三方模块的引入
    os 及 sys 模块补充
    如何白嫖视频会员
    python和SAS的思考
    5、根据进程号PID查询其服务路径
    5、安装mongodb 异常
    2、shell 判断字符串是否包含另一个字符串
    【九校2D2T1】旋转子段
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5308224.html
Copyright © 2020-2023  润新知