zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    自定义View的ToolBar布局报错Error:(2) No resource identifier found for attribute 'context' in package 'c
    在学git之主分支 branch
    获取发布版SHA1
    关于开启线程与UI的操作
    播放音频和视频(VideoView控件)
    通知栏Notification的应用
    Android 真机调式 Installation failed with message 远程主机强迫关闭了一个现有的连接。. It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing. WA
    运行程序申请危险权限
    mysql乐观锁总结和实践
    Nginx配置文件nginx.conf中文详解
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4722110.html
Copyright © 2011-2022 走看看