zoukankan      html  css  js  c++  java
  • HDU 5692 Snacks bfs版本dfs序 线段树

    Snacks

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5692

    Description

    百度科技园内有n个零食机,零食机之间通过n−1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。

    由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。

    为小度熊规划一个路线,使得路线上的价值总和最大。

    Input

    输入数据第一行是一个整数T(T≤10),表示有T组测试数据。

    对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。

    接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。

    接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。

    接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

    本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上:

    #pragma comment(linker, "/STACK:1024000000,1024000000")

    Output

    对于每组数据,首先输出一行”Case #?:”,在问号处应填入当前数据的组数,组数从1开始计算。

    对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

    Sample Input

    1
    6 5
    0 1
    1 2
    0 3
    3 4
    5 3
    7 -5 100 20 -5 -7
    1 1
    1 3
    0 2 -1
    1 1
    1 5

    Sample Output

    Case #1:
    102
    27
    2
    20

    Hint

    题意

    题解:

    第一个想法去熟练剖分了,导致智障了一下……

    每个点维护从根到这个点的权值和

    其实就是dfs序维护子树就好了,修改这个点的值,只会修改子树的值

    然后输出这个子树的最大值就好了……

    注意,这个傻逼题会爆栈,所以得用bfs去写dfs序

    代码

    #include<stdio.h>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<iostream>
    #include<cstring>
    #include<math.h>
    using namespace std;
    const int maxn = 1e5+7;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    typedef long long SgTreeDataType;
    struct treenode
    {
        int L , R  ;
        SgTreeDataType sum , lazy;
        void update(SgTreeDataType v)
        {
            sum += v;
            lazy += v;
        }
    };
    
    treenode tree[maxn*4];
    
    inline void push_down(int o)
    {
        SgTreeDataType lazyval = tree[o].lazy;
        tree[2*o].update(lazyval) ; tree[2*o+1].update(lazyval);
        tree[o].lazy = 0;
    }
    
    inline void push_up(int o)
    {
        tree[o].sum = max(tree[2*o].sum , tree[2*o+1].sum);
    }
    
    inline void build_tree(int L , int R , int o)
    {
        tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy = 0;
        if (R > L)
        {
            int mid = (L+R) >> 1;
            build_tree(L,mid,o*2);
            build_tree(mid+1,R,o*2+1);
        }
    }
    
    inline void update(int QL,int QR,SgTreeDataType v,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR) tree[o].update(v);
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            if (QL <= mid) update(QL,QR,v,o*2);
            if (QR >  mid) update(QL,QR,v,o*2+1);
            push_up(o);
        }
    }
    
    inline SgTreeDataType query(int QL,int QR,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR) return tree[o].sum;
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            SgTreeDataType res = -(1LL<<62);
            if (QL <= mid) res = max(res,query(QL,QR,2*o));
            if (QR > mid) res = max(res,query(QL,QR,2*o+1));
            push_up(o);
            return res;
        }
    }
    vector<int> E[maxn];
    int in[maxn],out[maxn],fa[maxn],n,m;
    long long Ex[maxn],val[maxn],cnt;
    stack<int> S;
    vector<int> V;
    void getdfs()
    {
        S.push(1);
        while(!S.empty())
        {
            int now = S.top();
            S.pop();
            V.push_back(now);
            in[now]=out[now]=++cnt;
            for(int i=0;i<E[now].size();i++)
            {
                int v = E[now][i];
                if(v==fa[now])continue;
                fa[v]=now;
                Ex[v]=Ex[now]+val[v];
                S.push(v);
            }
        }
    }
    void init()
    {
        for(int i=0;i<maxn;i++)E[i].clear();
        cnt=0;
        V.clear();
        while(!S.empty())S.pop();
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(fa,0,sizeof(fa));
    }
    void solve(int cas)
    {
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x++,y++;
            E[x].push_back(y);
            E[y].push_back(x);
        }
        for(int i=1;i<=n;i++)scanf("%lld",&val[i]);
        Ex[1]=val[1];
        build_tree(1,n,1);
        getdfs();
        reverse(V.begin(),V.end());
        for(int i=0;i<V.size();i++)
        {
            int p = V[i];
            update(in[p],in[p],Ex[p],1);
            for(int j=0;j<E[p].size();j++)
            {
                int v = E[p][j];
                if(v==fa[p])continue;
                out[p]=max(out[p],out[v]);
            }
        }
        printf("Case #%d:
    ",cas);
        while(m--)
        {
            int ppp = read(),x = read();
            x++;
            if(ppp==0){
                long long y;
                scanf("%lld",&y);
                update(in[x],out[x],y-val[x],1);
                val[x]=y;
            }
            else
                printf("%lld
    ",query(in[x],out[x],1));
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int i=1;i<=t;i++)solve(i);
        return 0;
    }
  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5516142.html
Copyright © 2011-2022 走看看