zoukankan      html  css  js  c++  java
  • BZOJ3589: 动态树

    3589: 动态树

    Time Limit: 30 Sec  Memory Limit: 1024 MB
    Submit: 174  Solved: 79
    [Submit][Status]

    Description

      小明在楼下种了一棵动态树, 该树每天会在某些节点上长出一些果子. 这棵树的根节点为1, 它有n个节点, n-1条边.

      别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件

      事件0:
      这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子.

      事件1:
      小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝, 让你求出在这些树枝上的节点的果子数的和. 注意, 树枝之间可能会重合, 这时重合的部分的节点的果子只要算一次.

      初始时, 每个节点上都没有果子.

    Input

      第一行一个整数n(1<=n<=200,000), 即节点数.
      接下来n-1行, 每行两个数字u, v. 表示果子u和果子v之间有一条直接的边. 节点从1开始编号.
      在接下来一个整数nQ(1<=nQ<=200,000), 表示事件.
      最后nQ行, 每行开头要么是0, 要么是1.
      如果是0, 表示这个事件是事件0. 这行接下来的2个整数u, delta表示以u为根的子树中的每个节点长出了delta个果子.
      如果是1, 表示这个事件是事件1. 这行接下来一个整数K(1<=K<=5), 表示这次询问涉及K个树枝. 接下来K对整数u_k, v_k, 每个树枝从节点u_k到节点v_k. 由于果子数可能非常多, 请输出这个数模2^31的结果.

    Output

      对于每个事件1, 输出询问的果子数.

    Sample Input


    5
    1 2
    2 3
    2 4
    1 5
    3
    0 1 1
    0 2 3
    1 2 3 1 1 4

    Sample Output

    13

    HINT

     1 <= n <= 200,000, 1 <= nQ <= 200,000, K = 5.


    生成每个树枝的过程是这样的:先在树中随机找一个节点, 然后在这个节点到根的路径上随机选一个节点, 这两个节点就作为树枝的两端.

    Source

    题解:
    各种逗逼。。。
    一个暴力的思路是我们每次沿边走然后打上标记,最后输出有标记的点的和。这样是可以过的。
    然后我写完之后狂WA不止。。。
    对排了几组发现两个标记下传的顺序搞反了。。。T_T
    代码:
      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 250000+5
     26 
     27 #define maxm 500+100
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 
     45 using namespace std;
     46 
     47 inline int read()
     48 
     49 {
     50 
     51     int x=0,f=1;char ch=getchar();
     52 
     53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     54 
     55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     56 
     57     return x*f;
     58 
     59 }
     60 int n,m,q,tot,head[maxn],a[10],b[10],top[maxn],id[maxn][2],son[maxn],dep[maxn],s[maxn],fa[maxn];
     61 struct edge{int go,next;}e[2*maxn];
     62 struct seg{int l,r,tag[2],sum,ret;}t[4*maxn];
     63 inline void insert(int x,int y)
     64 {
     65     e[++tot]=(edge){y,head[x]};head[x]=tot;
     66     e[++tot]=(edge){x,head[y]};head[y]=tot;
     67 }
     68 inline void dfs(int x)
     69 {
     70     s[x]=1;
     71     for(int i=head[x],y;i;i=e[i].next)
     72         if(!dep[y=e[i].go])
     73         {
     74             dep[y]=dep[x]+1;fa[y]=x;
     75             dfs(y);
     76             s[x]+=s[y];
     77             if(s[y]>s[son[x]])son[x]=y;
     78         }
     79 }
     80 inline void dfs2(int x,int chain)
     81 {
     82     id[x][0]=++m;top[x]=chain;
     83     if(son[x])dfs2(son[x],chain);
     84     for(int i=head[x];i;i=e[i].next)if(e[i].go!=son[x]&&e[i].go!=fa[x])dfs2(e[i].go,e[i].go);
     85     id[x][1]=m;
     86 }
     87 inline void pushup(int k)
     88 {
     89     t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
     90     t[k].ret=t[k<<1].ret+t[k<<1|1].ret;
     91     //cout<<k<<' '<<t[k].sum<<' '<<t[k].ret<<endl;
     92 }
     93 inline void build(int k,int l,int r)
     94 {
     95     t[k].l=l;t[k].r=r;int mid=(l+r)>>1;t[k].tag[0]=-1;
     96     if(l==r)return;
     97     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
     98 }
     99 inline void same(int k,int z)
    100 {
    101     t[k].tag[0]=z;t[k].ret=z==1?t[k].sum:0;
    102 }
    103 inline void update(int k,int z)
    104 {
    105     t[k].tag[1]+=z;t[k].sum+=(t[k].r-t[k].l+1)*z;
    106 }
    107 inline void pushdown(int k)
    108 {
    109     if(t[k].tag[1]){update(k<<1,t[k].tag[1]);update(k<<1|1,t[k].tag[1]);t[k].tag[1]=0;}
    110     if(t[k].tag[0]!=-1){same(k<<1,t[k].tag[0]);same(k<<1|1,t[k].tag[0]);t[k].tag[0]=-1;}
    111 }
    112 inline void change(int k,int x,int y,int z)
    113 {
    114     if(t[k].tag[0]==z)return;
    115     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    116     if(l==x&&r==y){same(k,z);return;}
    117     pushdown(k);
    118     if(y<=mid)change(k<<1,x,y,z);
    119     else if(x>mid)change(k<<1|1,x,y,z);
    120     else change(k<<1,x,mid,z),change(k<<1|1,mid+1,y,z);
    121     pushup(k);
    122 }
    123 inline void add(int k,int x,int y,int z)
    124 {
    125     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    126     if(l==x&&r==y){update(k,z);return;}
    127     pushdown(k);
    128     if(y<=mid)add(k<<1,x,y,z);
    129     else if(x>mid)add(k<<1|1,x,y,z);
    130     else add(k<<1,x,mid,z),add(k<<1|1,mid+1,y,z);
    131     pushup(k);
    132 }
    133 inline void solve(int x,int y,int z)
    134 {
    135     while(top[x]!=top[y])
    136     {
    137         if(dep[top[x]]<dep[top[y]])swap(x,y);
    138         change(1,id[top[x]][0],id[x][0],z);
    139         x=fa[top[x]];
    140     }
    141     if(dep[x]>dep[y])swap(x,y);
    142     change(1,id[x][0],id[y][0],z);
    143 }
    144 
    145 int main()
    146 
    147 {
    148 
    149     freopen("input.txt","r",stdin);
    150 
    151     freopen("output.txt","w",stdout);
    152 
    153     n=read();
    154     for1(i,n-1)insert(read(),read());
    155     dep[1]=1;dfs(1);dfs2(1,1);
    156     build(1,1,n);
    157     q=read();
    158     while(q--)
    159     {
    160         int ch=read();m=read();
    161         if(!ch)add(1,id[m][0],id[m][1],read());
    162         else 
    163         {
    164             for1(i,m)a[i]=read(),b[i]=read();
    165             for1(i,m)solve(a[i],b[i],1);
    166             printf("%d
    ",t[1].ret&2147483647);
    167             for1(i,m)solve(a[i],b[i],0);
    168         }
    169     }
    170 
    171     return 0;
    172 
    173 } 
    View Code
  • 相关阅读:
    更新自己知识的网站
    CRM IFD 部署在同一台服务器上遇到的错误
    Dynamics CRM 修改Excel 最大导出记录限制及 最大上传文件限制
    CRM 插件奇怪的报错
    单实例,当MongoDB单表数据文件太大导致写入速度变慢
    MongoDB分片实战
    SpringCloud使用feign时的复杂参数传递(转)
    99%的人都理解错了HTTP中GET与POST的区别(转)
    MySQL 数据导入 Unknown MySQL server host 'localhost'
    会员积分体系设计思路(转)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4142864.html
Copyright © 2011-2022 走看看