• [BZOJ1984] 月下“毛景树”|树链剖分|线段树


    1984: 月下“毛景树”

    Time Limit: 20 Sec  Memory Limit: 64 MB
    Submit: 1088  Solved: 348
    [Submit][Status][Discuss]

    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个。

    HINT

     

    Source

     
    1071046 ws_fqk 1984 Wrong_Answer 44644 kb 904 ms C++/Edit 5488 B 2015-08-11 19:22:07
    1071034 ws_fqk 1984 Wrong_Answer 44644 kb 924 ms C++/Edit 5470 B 2015-08-11 19:15:21
    1071019 ws_fqk 1984 Wrong_Answer 42304 kb 960 ms C++/Edit 5312 B 2015-08-11 19:08:32
    1071018 ws_fqk 1984 Wrong_Answer 43464 kb 92 ms C++/Edit 4179 B 2015-08-11 19:07:15
    1071006 ws_fqk 1984 Time_Limit_Exceed kb ms C++/Edit 5314 B 2015-08-11 18:55:07
    1071002 ws_fqk 1984 Time_Limit_Exceed kb ms C++/Edit 5308 B 2015-08-11 18:51:23
    1070994 ws_fqk 1984 Runtime_Error 21988 kb 976 ms C++/Edit 5308 B 2015-08-11 18:42:40

    已经给跪了……

    大体思路就是把边权压到点上,具体做法可以自己YY,询问时处理一下就好。hzwer学长是压到了深度小的点,我是压到了深度大的点。

    UPD:8.13 终于A掉了!

    1072820 ws_fqk 1984 Accepted 23968 kb 5604 ms C++/Edit 4935 B 2015-08-13 11:00:58
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<queue>
    #define N 100005
    using namespace std;
    int head[N],next[2*N],list[2*N],key[2*N];
    int l[4*N],r[4*N],tagadd[4*N],tagchange[4*N],size[N],mx[4*N],c[N],fa[N][20],deep[N],id[N],belong[N];
    int n,cnt,dfn;
    struct node {int u,v,w;} e[N];
    char ch[10];
    inline int read()
    {
        int a=0,f=1; char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
        return a*f;
    }
    inline void insert(int x,int y,int z)
    {
        next[++cnt]=head[x];
        head[x]=cnt;
        list[cnt]=y;
        key[cnt]=z;
    }
    void dfs1(int x)
    {
        size[x]=1;
        for (int i=1;(1<<i)<=deep[x];i++) fa[x][i]=fa[fa[x][i-1]][i-1];
        for (int i=head[x];i;i=next[i])
        {
            if (list[i]==fa[x][0]) continue;
            fa[list[i]][0]=x;
            c[list[i]]+=key[i];
            deep[list[i]]=deep[x]+1;
            dfs1(list[i]);
            size[x]+=size[list[i]];
        }
    }
    void dfs2(int x,int chain)
    {
        belong[x]=chain;
        id[x]=++dfn;
        int k=0;
        for (int i=head[x];i;i=next[i])
            if (list[i]!=fa[x][0]&&size[list[i]]>size[k]) k=list[i];
        if (!k) return;
        dfs2(k,chain);
        for (int i=head[x];i;i=next[i])
            if (list[i]!=fa[x][0]&&list[i]!=k) dfs2(list[i],list[i]);
    }
    inline int lca(int x,int y)
    {
        if (deep[x]<deep[y]) swap(x,y);
        int t=deep[x]-deep[y];
        for (int i=0;(1<<i)<=t;i++)
            if ((1<<i)&t) x=fa[x][i];
        for (int i=18;i>=0;i--)
            if (fa[x][i]!=fa[y][i]) {x=fa[x][i]; y=fa[y][i];}
        return x==y?x:fa[x][0];
    }
    void build(int k,int x,int y)
    {
        l[k]=x; r[k]=y; tagchange[k]=-1;
        if (x==y) return;
        int mid=(x+y)>>1;
        build(k<<1,x,mid); build(k<<1|1,mid+1,y);
    }
    inline void pushup(int k)
    {
        mx[k]=max(mx[k<<1],mx[k<<1|1]);
    }
    inline void pushdown(int k)
    {
        if (l[k]==r[k]) return;
        if (tagchange[k]!=-1)
        {
            tagadd[k<<1]=tagadd[k<<1|1]=0;
            tagchange[k<<1]=tagchange[k<<1|1]=tagchange[k];
            mx[k<<1]=mx[k<<1|1]=tagchange[k];
            tagchange[k]=-1;
        }
        if (tagadd[k])
        {
            mx[k<<1]+=tagadd[k]; mx[k<<1|1]+=tagadd[k];
            if (tagchange[k<<1]!=-1) tagchange[k<<1]+=tagadd[k]; else tagadd[k<<1]+=tagadd[k];
            if (tagchange[k<<1|1]!=-1) tagchange[k<<1|1]+=tagadd[k]; else tagadd[k<<1|1]+=tagadd[k];
            tagadd[k]=0;
        }
    }
    void change(int k,int x,int y,int v)
    {
        pushdown(k);
        if (l[k]==x&&r[k]==y)
        {
            tagchange[k]=mx[k]=v;
            return;
        }
        int mid=(l[k]+r[k])>>1;
        if (y<=mid) change(k<<1,x,y,v);
        else if (x>mid) change(k<<1|1,x,y,v);
        else 
        {
            change(k<<1,x,mid,v);
            change(k<<1|1,mid+1,y,v);
        }
        pushup(k);
    }
    void add(int k,int x,int y,int v)
    {
        pushdown(k);
        if (l[k]==x&&r[k]==y)
        {
            tagadd[k]=v;
            mx[k]+=v;
            return;
        }
        int mid=(l[k]+r[k])>>1;
        if (y<=mid) add(k<<1,x,y,v);
        else if (x>mid) add(k<<1|1,x,y,v);
        else
        {
            add(k<<1,x,mid,v);
            add(k<<1|1,mid+1,y,v);
        }
        pushup(k);
    }
    int getmx(int k,int x,int y)
    {
        pushdown(k);
        if (l[k]==x&&r[k]==y) return mx[k];
        int mid=(l[k]+r[k])>>1;
        if (mid>=y) return getmx(k<<1,x,y);
        else if (mid<x)return getmx(k<<1|1,x,y);
        else return max(getmx(k<<1,x,mid),getmx(k<<1|1,mid+1,y));
    }
    inline void solvechange(int x,int f,int w)
    {
        while (belong[x]!=belong[f])
        {
            change(1,id[belong[x]],id[x],w);
            x=fa[belong[x]][0];
        }
        if (id[f]+1<=id[x]) change(1,id[f]+1,id[x],w);
    }
    inline int solvemax(int x,int f)
    {
        int ans=-1;
        while (belong[x]!=belong[f])
        {
            ans=max(ans,getmx(1,id[belong[x]],id[x]));
            x=fa[belong[x]][0];
        }
        if (id[f]+1<=id[x]) ans=max(ans,getmx(1,id[f]+1,id[x]));
        return ans;
    }
    inline void solveadd(int x,int f,int w)
    {
        while (belong[x]!=belong[f])
        {
            add(1,id[belong[x]],id[x],w);
            x=fa[belong[x]][0];
        }
        if (id[f]+1<=id[x]) add(1,id[f]+1,id[x],w);
    }
    int main()
    {
        n=read();
        for (int i=1;i<n;i++)
        {
            e[i].u=read(),e[i].v=read(),e[i].w=read();
            insert(e[i].u,e[i].v,e[i].w); insert(e[i].v,e[i].u,e[i].w);
        }
        dfs1(1); dfs2(1,1); build(1,1,n);    
        for (int i=1;i<=n;i++) change(1,id[i],id[i],c[i]);
        while (1)
        {
            scanf("%s",ch); 
            if (ch[1]=='t') break;
            int u=read(),v=read(),t,w;
            if (ch[1]=='a') {t=lca(u,v); printf("%d
    ",max(solvemax(u,t),solvemax(v,t)));}
            if (ch[1]=='o') {w=read(); t=lca(u,v); solvechange(u,t,w); solvechange(v,t,w);}
            if (ch[1]=='d') {w=read(); t=lca(u,v); solveadd(u,t,w); solveadd(v,t,w);} 
            if (ch[1]=='h') {if (deep[e[u].v]<deep[e[u].u]) change(1,id[e[u].u],id[e[u].u],v); else change(1,id[e[u].v],id[e[u].v],v);}
        }
        return 0;
    }
  • 相关阅读:
    2020牛客暑期多校训练营(第三场)C-Operation Love(计算几何)
    洛谷 P3376 【模板】网络最大流
    2020牛客暑假多校训练营(第二场)F-Fake Maxpooling(单调队列)
    Codeforces Round #655 (Div. 2)【ABCD】(题解)
    Codeforces Round #648 (Div. 2)【ABCDEF】(题解)
    Codeforces Round #647 (Div. 2)
    Codeforces Round #646 (Div. 2)【ABCDE】(题解)
    Educational Codeforces Round 88 (Rated for Div. 2)【ABCDE】(题解)
    [蓝帽杯2020]一个利用data伪协议和include,file_get_contents写shell的web题
    [网鼎杯2020朱雀场] misc部分题解
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4722110.html
Copyright © 2020-2023  润新知