hdu5692(dfs序+线段树 )Snacks

来源:互联网 发布:韩子高网络剧有下部吗 编辑:程序博客网 时间:2024/05/30 05:15



Snacks

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3022    Accepted Submission(s): 703


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

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

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

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

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

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

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

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

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

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

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

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

Sample Input
16 50 11 20 33 45 37 -5 100 20 -5 -71 11 30 2 -11 11 5
 

Sample Output
Case #1:10227220
 

Source
2016"百度之星" - 初赛(Astar Round2A
//dfs序+线段树//居然忘记了开4倍的空间,还有边的两倍空间,wa了半天。。。。。。#pragma comment(linker, "/STACK:1024000000,1024000000")#include<cstdio>#include<iostream>#include<cstring>#define LL long longusing namespace std;const int mn=100005;int n,m,head[mn],tot,val[mn],L[mn],r[mn],index;LL s[mn],tr[mn<<2],lazy[mn<<2];struct Edge{    int to,next;} edges[mn*2];void add(int u,int v){    edges[tot].to=v;    edges[tot].next=head[u];    head[u]=tot++;}void dfs(int u,int f){    L[u]=++index;    for(int i=head[u]; ~i; i=edges[i].next)    {        int v=edges[i].to;        if(f==v) continue;        s[index+1]=val[v]+s[L[u]];        dfs(v,u);    }    r[u]=index;}void pushdown(int i){    //更新子树的信息    if(lazy[i])    {        lazy[i*2]+=lazy[i];        lazy[i*2+1]+=lazy[i];        tr[i*2]+=lazy[i];        tr[i*2+1]+=lazy[i];        lazy[i]=0;    }}void pushup(int rt){    tr[rt]=max(tr[rt*2],tr[rt*2+1]);}void build(int l,int r,int rt){    if(l==r)    {        tr[rt]=s[l];        return;    }    int mid=(l+r)/2;    build(l,mid,rt*2);    build(mid+1,r,rt*2+1);    pushup(rt);}void update(int l,int r,int ll,int rr,int rt,int ad){    if(l>=ll&&r<=rr)    {        lazy[rt]+=ad;        tr[rt]+=ad;        return;    }    pushdown(rt);    int mid=(l+r)/2;    if(ll<=mid&&rr>=l) update(l,mid,ll,rr,rt*2,ad);    if(ll<=r&&rr>=mid+1) update(mid+1,r,ll,rr,rt*2+1,ad);    pushup(rt);}LL query(int l,int r,int ll,int rr,int rt){    if(ll<=l&&rr>=r) return tr[rt];    pushdown(rt);    int mid=(l+r)/2;    LL ans=-1e18;    if(ll<=mid&&rr>=l) ans=max(ans,query(l,mid,ll,rr,rt*2));    if(ll<=r&&rr>=mid+1) ans=max(ans,query(mid+1,r,ll,rr,rt*2+1));    return ans;}int main(){    int T,kase=0,op,x,y;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        tot=0;        for(int i=1; i<n; ++i)        {            scanf("%d%d",&x,&y);            add(x,y);            add(y,x);        }        for(int i=0; i<n; ++i)            scanf("%d",val+i);        index=0;        s[1]=val[0];        dfs(0,-1);        build(1,n,1);        memset(lazy,0,sizeof(lazy));        printf("Case #%d:\n",++kase);        while(m--)        {            scanf("%d%d",&op,&x);            if(op)                printf("%lld\n",query(1,n,L[x],r[x],1));            else            {                scanf("%d",&y);                update(1,n,L[x],r[x],1,y-val[x]);                val[x]=y;            }        }    }    return 0;}