zoukankan      html  css  js  c++  java
  • 月下“毛景树”

    Description
    毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数:     Change k w:将第k条树枝上毛毛果的个数改变为w个。  Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。     Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问:     Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
    Input
    第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。
    Output
    对于毛毛虫的每个询问操作,输出一个答案。
    Sample Input
    4
    1 2 8
    1 3 7
    3 4 9
    Max 2 4
    Cover 2 4 5
    Add 1 4 10
    Change 1 16
    Max 2 4
    Stop
    Sample Output
    9
    16
    【Data Range】
    1<=N<=100,000,操作+询问数目不超过100,000。
    保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。
    题面

    解题思路:边权化点权,将边权放到深度较深的点上面

    对于操作:
    Change k w:将第k条树枝上毛毛果的个数改变为w个。
    =>直接找对应的点,线段树上单点修改
    Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。
    =>注意:u和v的lca是不应该被修改的
    为了方便,我们可以先修改,再把lca改回去
    Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。
    =>注意:u和v的lca是不应该被加的
    为了方便,我们可以先修改,再把lca减回去
    Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
    =>注意:u和v的lca是不应该被算进去的
    我们可以先将lca赋成极小值
    得到答案后在将原值赋回去
    值得注意的地方是线段树的标记下放:
    先修改操作,后加操作,保证正确性

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const ll N=1e5+10;
      5 struct node{
      6     ll u,v,c,ne;
      7 }e[N*2];
      8 ll h[N],tot,n;
      9 void add(ll u,ll v,ll c)
     10 {
     11     tot++;e[tot]=(node){u,v,c,h[u]};h[u]=tot;
     12     e[tot+n-1]=(node){v,u,c,h[v]};h[v]=tot+n-1;
     13 }
     14 ll dep[N],size[N],son[N],f[N];
     15 ll val[N],w[N],id[N],top[N];
     16 ll Max[N*6],ad[N*6],fg[N*6];
     17 void build(ll o,ll l,ll r)
     18 {
     19     fg[o]=-1;ad[o]=0;
     20     if(l==r){
     21         Max[o]=w[l];
     22         return;
     23     }
     24     ll mid=(l+r)>>1;
     25     build(o<<1,l,mid);build(o<<1|1,mid+1,r);
     26     Max[o]=max(Max[o<<1],Max[o<<1|1]);
     27 }
     28 void down(ll o)
     29 {
     30     if(fg[o]!=-1)
     31     {
     32         fg[o<<1]=Max[o<<1]=fg[o];
     33         fg[o<<1|1]=Max[o<<1|1]=fg[o];
     34         ad[o<<1]=ad[o<<1|1]=0;
     35         fg[o]=-1;
     36     }
     37     if(ad[o])
     38     {
     39         Max[o<<1]+=ad[o];Max[o<<1|1]+=ad[o];
     40         if(fg[o<<1]!=-1) fg[o<<1]+=ad[o];
     41         else ad[o<<1]+=ad[o];
     42         if(fg[o<<1|1]!=-1) fg[o<<1|1]+=ad[o];
     43         else ad[o<<1|1]+=ad[o];
     44         ad[o]=0;
     45     }
     46 }
     47 void tchange(ll o,ll l,ll r,ll x,ll y,ll k)
     48 {
     49     if(x<=l && y>=r)
     50     {
     51         Max[o]=k;fg[o]=k;ad[o]=0;
     52         return;
     53     }
     54     down(o);
     55     ll mid=(l+r)>>1;
     56     if(x<=mid) tchange(o<<1,l,mid,x,y,k);
     57     if(y>=mid+1) tchange(o<<1|1,mid+1,r,x,y,k);
     58     Max[o]=max(Max[o<<1],Max[o<<1|1]);
     59 }
     60 void tadd(ll o,ll l,ll r,ll x,ll y,ll k)
     61 {
     62     if(x<=l && y>=r)
     63     {
     64         ad[o]+=k;Max[o]+=k;
     65         return;
     66     }
     67     down(o);
     68     ll mid=(l+r)>>1;
     69     if(x<=mid) tadd(o<<1,l,mid,x,y,k);
     70     if(y>=mid+1) tadd(o<<1|1,mid+1,r,x,y,k);
     71     Max[o]=max(Max[o<<1],Max[o<<1|1]);
     72 }
     73 ll tquery(ll o,ll l,ll r,ll x,ll y)
     74 {
     75     if(x<=l && y>=r) return Max[o];
     76     down(o);
     77     ll mid=(l+r)>>1,tmp=-1e9;
     78     if(x<=mid) tmp=max(tmp,tquery(o<<1,l,mid,x,y));
     79     if(y>=mid+1) tmp=max(tmp,tquery(o<<1|1,mid+1,r,x,y));
     80     return tmp;
     81 }
     82 void dfs1(ll u)
     83 {
     84     size[u]=1;ll p=-1;
     85     for(ll i=h[u],rr;i;i=e[i].ne)
     86     {
     87         rr=e[i].v;
     88         if(!dep[rr])
     89         {
     90             dep[rr]=dep[u]+1;f[rr]=u;val[rr]=e[i].c;
     91             dfs1(rr);size[u]+=size[rr];
     92             if(size[rr]>p)
     93              p=size[rr],son[u]=rr;
     94         }
     95     }
     96 }
     97 void dfs2(ll u,ll up)
     98 {
     99     if(u==0) return;
    100     id[u]=++tot;w[tot]=val[u];
    101     top[u]=up;
    102     dfs2(son[u],up);
    103     for(ll i=h[u],rr;i;i=e[i].ne)
    104     {
    105         rr=e[i].v;
    106         if(rr!=f[u] && rr!=son[u]) dfs2(rr,rr);
    107     }
    108 }
    109 void Qchange(ll x,ll y,ll k)
    110 {
    111     while(top[x]!=top[y])
    112     {
    113         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    114         tchange(1,1,n,id[top[x]],id[x],k);
    115         x=f[top[x]];
    116     }
    117     if(dep[x]>dep[y]) swap(x,y);
    118     tchange(1,1,n,id[x],id[y],k);
    119 }
    120 void Qadd(ll x,ll y,ll k)
    121 {
    122     while(top[x]!=top[y])
    123     {
    124         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    125         tadd(1,1,n,id[top[x]],id[x],k);
    126         x=f[top[x]];
    127     }
    128     if(dep[x]>dep[y]) swap(x,y);
    129     tadd(1,1,n,id[x],id[y],k);
    130 }
    131 ll Qmax(ll x,ll y)
    132 {
    133     ll ans=-1;
    134     while(top[x]!=top[y])
    135     {
    136         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    137         ans=max(ans,tquery(1,1,n,id[top[x]],id[x]));
    138         x=f[top[x]];
    139     }
    140     if(dep[x]>dep[y]) swap(x,y);
    141     ans=max(ans,tquery(1,1,n,id[x],id[y]));
    142     return ans;
    143 }
    144 ll lca(ll x,ll y)
    145 {
    146     while(top[x]!=top[y])
    147     {
    148         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    149         x=f[top[x]];
    150     }
    151     if(dep[x]>dep[y]) swap(x,y);
    152     return x;
    153 }
    154 char op[10];
    155 ll x,y,z,fa,tmp;
    156 int main()
    157 {
    158     scanf("%lld",&n);
    159     for(ll i=1;i<=n-1;++i)
    160     {
    161         scanf("%lld%lld%lld",&x,&y,&z);
    162         add(x,y,z);
    163     }
    164     dep[1]=1;dfs1(1);
    165     val[1]=-1e9;tot=0;dfs2(1,1);
    166     build(1,1,n);
    167     while(scanf("%s",op)!=EOF)
    168     {
    169         if(op[1]=='t') break;
    170         if(op[1]=='h')//将第x条树枝上毛毛果的个数改变为y个
    171         {
    172             scanf("%lld%lld",&x,&y);
    173             x=(dep[e[x].u]>dep[e[x].v] ? e[x].u:e[x].v);
    174             tchange(1,1,n,id[x],id[x],y);
    175         }
    176         if(op[1]=='o')//将节点x与节点y之间的都改变为z个
    177         {
    178             scanf("%lld%lld%lld",&x,&y,&z);
    179             fa=lca(x,y);tmp=tquery(1,1,n,id[fa],id[fa]);
    180             Qchange(x,y,z);tchange(1,1,n,id[fa],id[fa],tmp);
    181         }
    182         if(op[1]=='d')//将节点x与节点y之间的都增加z个
    183         {
    184             scanf("%lld%lld%lld",&x,&y,&z);
    185             fa=lca(x,y);
    186             Qadd(x,y,z);tadd(1,1,n,id[fa],id[fa],-z);
    187         }
    188         if(op[1]=='a')//询问节点x与节点y之间最多有多少个
    189         {
    190             scanf("%lld%lld",&x,&y);
    191             fa=lca(x,y);tmp=tquery(1,1,n,id[fa],id[fa]);
    192             tchange(1,1,n,id[fa],id[fa],-1e9);
    193             printf("%lld
    ",Qmax(x,y));
    194             tchange(1,1,n,id[fa],id[fa],tmp);
    195         }
    196     }
    197     return 0;
    198 }
    代码
  • 相关阅读:
    git clone GitLab 工程报错Repository not found
    vue + Element-ui 实现分页
    Element-ui 实现table的合计功能
    python 使用UUID库生成唯一ID
    css 设置overflow:scroll 滚动条的样式
    下载css-loader 安装及使用
    vue实现首页导航切换不同路由的方式(二)【使用vuex实现的】
    vue实现随机验证码功能
    vue实现首页导航切换不同路由的方式
    vue实现菜单切换
  • 原文地址:https://www.cnblogs.com/adelalove/p/8709620.html
Copyright © 2011-2022 走看看