hdu 5052 Yaoge’s maximum profit 树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
来源:互联网 发布:三国志9pk优化补丁版 编辑:程序博客网 时间:2024/06/05 05:55
题意:
给定n个点构成的树,每个点都有点权。
下面n行给出每个点点权表示每个点买卖鸡腿的价格
下面n-1行给出树边
下面Q个操作
Q行
u, v, val
从u走到v,过程中可以买一个鸡腿,然后到后面卖掉,输出max(0, 最大的收益)
然后给[u,v]路径上点点权+=x
思路:树链剖分,做过bzoj2243后基本上稍微想下就会有思路。线段树中需要维护区间最大值Max,区间最小值Min,懒惰标记tag,
区间沿正方向可获得的最大利润ans1,区间沿反方向可获得的最大利润ans2。在solve中需要记录上次剖分结果,根据方向决定是更新
minl(正向更新minl)还是maxr(反向更新maxr),以及要知道当前剖分区间的最大值Max和最小值Min,通过这些值不断更新ans。详
见代码:
/********************************************************* file name: hdu5052.cpp author : kereo create time: 2015年01月26日 星期一 13时13分26秒*********************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int sigma_size=26;const int N=100+50;const int MAXN=50000+50;const int inf=0x3fffffff;const double eps=1e-8;const int mod=100000000+7;#define L(x) (x<<1)#define R(x) (x<<1|1)#define PII pair<int, int>#define mk(x,y) make_pair((x),(y))int n,m,edge_cnt,cnt;int head[MAXN],sz[MAXN],fa[MAXN],son[MAXN],top[MAXN],dep[MAXN],pos[MAXN],a[MAXN];struct Edge{ int v,next;}edge[MAXN<<1];struct node{ int l,r; int Min,Max,tag,ans1,ans2; //ans1表示沿正方向(->)的最大profit,ans2表示沿着反方向的最大profit}segtree[MAXN<<2];void init(){ edge_cnt=cnt=0; memset(head,-1,sizeof(head));}void addedge(int u,int v){ edge[edge_cnt].v=v; edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;}void dfs1(int u,int pre,int depth){ sz[u]=1; fa[u]=pre; son[u]=0; dep[u]=depth; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v == pre) continue; dfs1(v,u,depth+1); sz[u]+=sz[v]; if(sz[son[u]]<sz[v]) son[u]=v; }}void dfs2(int u,int tp){ pos[u]=++cnt; top[u]=tp; if(son[u]!=0) dfs2(son[u],top[u]); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v == fa[u] || v == son[u]) continue; dfs2(v,v); }}void push_down(int rt){ if(segtree[rt].tag){ segtree[L(rt)].tag+=segtree[rt].tag; segtree[L(rt)].Max+=segtree[rt].tag; segtree[L(rt)].Min+=segtree[rt].tag; segtree[R(rt)].tag+=segtree[rt].tag; segtree[R(rt)].Max+=segtree[rt].tag; segtree[R(rt)].Min+=segtree[rt].tag; segtree[rt].tag=0; }}void push_up(int rt){ segtree[rt].Min=min(segtree[L(rt)].Min,segtree[R(rt)].Min); segtree[rt].Max=max(segtree[L(rt)].Max,segtree[R(rt)].Max); segtree[rt].ans1=max(segtree[R(rt)].Max-segtree[L(rt)].Min,max(segtree[L(rt)].ans1,segtree[R(rt)].ans1)); segtree[rt].ans2=max(segtree[L(rt)].Max-segtree[R(rt)].Min,max(segtree[L(rt)].ans2,segtree[R(rt)].ans2));}void build(int rt,int l,int r){ segtree[rt].l=l; segtree[rt].r=r; segtree[rt].Max=segtree[rt].Min=0; segtree[rt].tag=segtree[rt].ans1=segtree[rt].ans2=0; if(l == r) return ; int mid=(l+r)>>1; build(L(rt),l,mid); build(R(rt),mid+1,r);}void update(int rt,int l,int r,int x){ if(segtree[rt].l == l && segtree[rt].r == r){ segtree[rt].tag+=x; segtree[rt].Max+=x; segtree[rt].Min+=x; return ; } push_down(rt); int mid=(segtree[rt].l+segtree[rt].r)>>1; if(r<=mid) update(L(rt),l,r,x); else if(l>mid) update(R(rt),l,r,x); else{ update(L(rt),l,mid,x); update(R(rt),mid+1,r,x); } push_up(rt);}int query(int rt,int l,int r,int id,int &Max,int &Min){ if(segtree[rt].l == l && segtree[rt].r == r){ Max=segtree[rt].Max; Min=segtree[rt].Min; if(id == 1) return segtree[rt].ans1; else return segtree[rt].ans2; } push_down(rt); int mid=(segtree[rt].l+segtree[rt].r)>>1; if(r<=mid) return query(L(rt),l,r,id,Max,Min); else if(l>mid) return query(R(rt),l,r,id,Max,Min); else{ int minl=0,maxl=0,minr=0,maxr=0,ans; ans=max(query(L(rt),l,mid,id,maxl,minl),query(R(rt),mid+1,r,id,maxr,minr)); Max=max(maxl,maxr); Min=min(minl,minr); if(id == 1) ans=max(ans,maxr-minl); else ans=max(ans,maxl-minr); return ans; } push_up(rt);}int solve(int u,int v,int id,int w){ //从u到v int ans=0; if(id == 0){ int Max=-inf,Min=inf,minl=inf,maxr=-inf; while(top[u]!=top[v]){ if(dep[top[u]]>dep[top[v]]){ ans=max(ans,query(1,pos[top[u]],pos[u],2,Max,Min)); ans=max(ans,Max-minl); minl=min(minl,Min); u=fa[top[u]]; } else{ ans=max(ans,query(1,pos[top[v]],pos[v],1,Max,Min)); ans=max(ans,maxr-Min); maxr=max(maxr,Max); v=fa[top[v]]; } } //printf("u=%d v=%d\n",u,v); if(dep[u]<dep[v]) ans=max(ans,query(1,pos[u],pos[v],1,Max,Min)); else ans=max(ans,query(1,pos[v],pos[u],2,Max,Min)); //printf("ans=%d Min=%d Max=%d minl=%d maxr=%d\n",ans,Min,Max,minl,maxr); ans=max(ans,Max-minl); ans=max(ans,maxr-Min); ans=max(ans,maxr-minl); //一开始漏了。。 //printf("-------------------------------\n"); } else { while(top[u]!=top[v]){ if(dep[top[u]]<dep[top[v]]) swap(u,v); update(1,pos[top[u]],pos[u],w); u=fa[top[u]]; } if(dep[u]>dep[v]) swap(u,v); update(1,pos[u],pos[v],w); } return ans;}int main(){ int T; //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--){ init(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs1(1,1,1); dfs2(1,1); build(1,1,n); /*for(int i=1;i<=n;i++) printf("pos[%d]=%d top[%d]=%d\n",i,pos[i],i,top[i]); printf("-------------------------------------\n");*/ for(int i=1;i<=n;i++) update(1,pos[i],pos[i],a[i]); scanf("%d",&m); while(m--){ int u,v,w; scanf("%d%d%d",&u,&v,&w); int ans=solve(u,v,0,0); solve(u,v,1,w); printf("%d\n",ans); } }return 0;}
0 0
- hdu 5052 Yaoge’s maximum profit 树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
- HDU 5052 Yaoge’s maximum profit 裸树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
- HDU Tree LCA 2014 ACM/ICPC Asia Regional Shanghai Online
- hdu 5045 Contest 2014 ACM/ICPC Asia Regional Shanghai Online
- hdu 5047 Sawtooth 2014 ACM/ICPC Asia Regional Shanghai Online
- 2014 ACM/ICPC Asia Regional Shanghai Online
- hdu 5052 Yaoge’s maximum profit(树链剖分)
- 【HDU】5052 Yaoge’s maximum profit 树链剖分
- hdu 5477(2015 ACM/ICPC Asia Regional Shanghai Online)
- hdu 5478(2015 ACM/ICPC Asia Regional Shanghai Online )
- 2015 ACM/ICPC Asia Regional Shanghai Online --HDU 5478
- 2015 ACM/ICPC Asia Regional Shanghai Online
- 2015 ACM/ICPC Asia Regional Shanghai Online
- 2015 ACM/ICPC Asia Regional Shanghai Online
- 2015 ACM/ICPC Asia Regional Shanghai Online
- 2014 ACM/ICPC Asia Regional Shanghai Online 1006 Sawtooth
- 2014 ACM/ICPC Asia Regional Shanghai Online 1009
- hdu5045||2014 ACM/ICPC Asia Regional Shanghai Online【数位dp】
- JavaScript判断浏览器类型及版本(新增IE11)
- oracle全攻略——简介
- ubuntu 14.01 amd64安装32库
- 实现PHP 转 ASCII
- ios 网络请求 笔记
- hdu 5052 Yaoge’s maximum profit 树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
- poj2195 Going Home 最小权值匹配
- Python 使用单链表实现多项式 (Polynomial)
- hibernate4.0+版本和3.0+版本的区别总结
- HDU 1233 贪心+并查集
- 如何打印错误日志
- Java heap dump触发和分析(转)
- -bash: ./dumpsga.sh: /bin/bash^M
- 链表部分知识