zoukankan      html  css  js  c++  java
  • [SHOI2012]魔法树

    题目传送门

    省选D2T3考板子可真是不多见呢。。。。~~~

    这题就是一个裸的树链剖分,对于每一个Add操作,维护从u至v的路径,对于每一个Query操作,询问以u为根的子树之和。如果不会树链剖分可以看我的往期博客,具体细节在代码之中就不多赘述了~

    下面给出参考代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #define N 400005
      4 #define M 800005
      5 #define lc k*2
      6 #define rc k*2+1
      7 #define mid (l+r)/2
      8 #define int long long
      9 using namespace std;
     10 struct node
     11 {
     12     int l,r,w,tag;
     13 }tree[4*N];
     14 int n,m,r,p,x,y,z;
     15 int v[M],head[M],nxt[M],cnt;
     16 int dep[N],fa[N],son[N],size[N],top[N],seg[N],id;
     17 char q;
     18 int read()
     19 {
     20     int x=0,f=1;char ch=getchar();
     21     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     22     while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
     23     return x*f;
     24 }
     25 void add(int a,int b)
     26 {
     27     v[++cnt]=b;
     28     nxt[cnt]=head[a];
     29     head[a]=cnt;
     30 }
     31 void dfs1(int node,int father)
     32 {
     33     dep[node]=dep[father]+1;
     34     fa[node]=father;
     35     size[node]=1;
     36     int maxson=-1;
     37     for(int i=head[node];i;i=nxt[i])
     38     {
     39         int go=v[i];
     40         if(go==father)continue;
     41         dfs1(go,node);
     42         size[node]+=size[go];
     43         if(size[go]>maxson)maxson=size[go],son[node]=go;
     44     }
     45 }
     46 void dfs2(int node,int topfather)
     47 {
     48     seg[node]=++id;
     49     top[node]=topfather;
     50     if(!son[node])return;
     51     dfs2(son[node],topfather);
     52     for(int i=head[node];i;i=nxt[i])
     53     {
     54         int go=v[i];
     55         if(go==fa[node]||go==son[node])continue;
     56         dfs2(go,go);
     57     }
     58 }
     59 void build(int l,int r,int k)
     60 {
     61     tree[k].l=l;tree[k].r=r;
     62     if(l==r)return;
     63     build(l,mid,lc);
     64     build(mid+1,r,rc);
     65 }
     66 void pushdown(int k)
     67 {
     68     tree[lc].tag+=tree[k].tag;
     69     tree[rc].tag+=tree[k].tag;
     70     tree[lc].w+=(tree[lc].r-tree[lc].l+1)*tree[k].tag;
     71     tree[rc].w+=(tree[rc].r-tree[rc].l+1)*tree[k].tag;
     72     tree[k].tag=0;
     73     return;
     74 }
     75 void pushup(int k)
     76 {
     77     tree[k].w=tree[lc].w+tree[rc].w;
     78     return;
     79 }
     80 void add(int x,int y,int k)
     81 {
     82     int l=tree[k].l,r=tree[k].r;
     83     if(l>=x&&r<=y)
     84     {
     85         tree[k].tag+=z;
     86         tree[k].w+=(r-l+1)*z;
     87         return;
     88     }
     89     if(tree[k].tag)pushdown(k);
     90     if(x<=mid)add(x,y,lc);
     91     if(y>mid)add(x,y,rc);
     92     pushup(k);
     93 }
     94 int query(int x,int y,int k)
     95 {
     96     int l=tree[k].l,r=tree[k].r;
     97     if(l>=x&&r<=y)
     98     {
     99         return tree[k].w;
    100     }
    101     if(tree[k].tag)pushdown(k);
    102     int res=0;
    103     if(x<=mid)res+=query(x,y,lc);
    104     if(y>mid)res+=query(x,y,rc);
    105     return res;
    106 }
    107 void Tadd(int x,int y)
    108 {
    109     while(top[x]!=top[y])
    110     {
    111         if(dep[top[x]]<dep[top[y]])swap(x,y);
    112         add(seg[top[x]],seg[x],1);
    113         x=fa[top[x]];
    114     }
    115     if(dep[x]>dep[y])swap(x,y);
    116     add(seg[x],seg[y],1);
    117 }
    118 int Treequery(int x)
    119 {
    120     return query(seg[x],seg[x]+size[x]-1,1);
    121 }
    122 signed main()
    123 {
    124     n=read();
    125     for(int i=1;i<n;i++)
    126     {
    127         x=read();y=read();
    128         x++;y++;
    129         add(x,y);add(y,x);
    130     }
    131     dfs1(1,0);dfs2(1,1);
    132     build(1,n,1);
    133     m=read();
    134     while(m--)
    135     {
    136         cin>>q;
    137         if(q=='A')
    138         {
    139             x=read();y=read();z=read();
    140             x++;y++;
    141             Tadd(x,y);
    142         }
    143         else
    144         {
    145             x=read();
    146             x++;
    147             cout<<Treequery(x)<<endl;
    148         }
    149     }
    150 }
    View Code
  • 相关阅读:
    @Value和@ConfigurationProperties
    mongodb为集合新增字段、删除字段、修改字段(转)
    mongoTemplate CURD 和模糊查询(转)
    在项目中使用Swagger接口说明
    mongodb 批量添加、修改和删除
    @SpringQueryMap注解 feign的get传参方式(转)
    Spring下的@Order和@Primary与javax.annotation-api下@Priority【Spring4.1后】等方法控制多实现的依赖注入(转)
    @RequestBody和@RequestParam区别
    Juit4 SpringBoot注解
    Spring Boot干货系列:(十二)Spring Boot使用单元测试(转)
  • 原文地址:https://www.cnblogs.com/szmssf/p/11145035.html
Copyright © 2011-2022 走看看