題解 【POJ3728】The merchant(LCA)
阿新 • • 發佈:2018-07-14
分享圖片 gist The open chan stdout node .org 圖片
題意:一棵樹有N個城市,每個城市商品價格不一樣,Q個詢問,問從u出發到達v點,每個城市只能經過一次的最大利潤
max min數組存u城到u的第2^i個祖先路徑上的最值
答案就是u-v路徑上的最大值-最小值
真的是這樣嗎?
仔細想想,買入點可能在賣出點之後嗎?當然不行
於是把路徑分成兩段
問題就變成下列三種情況
購買和賣出都在A段中完成
購買和賣出都在B段中完成
在A段中購買,B段中賣出
然後將A,B段分別進行處理(感覺像是dp的思想)
這還不夠,還要分方向進行處理
shun【u】表示從u往LCA走 dao【u】表示從LCA往u走
最後別忘了處理U-LCA購買,LCA-V賣出的情況
#include<cstdio> #define inf 0x3f3f3f3f #define N 50005 int n,q,a,b; int cnt; int val[N],head[N],dep[N]; int f[N][21],mx[N][21],mn[N][21],shun[N][21],dao[N][21]; void inline swap(int &a,int &b){ a^=b^=a^=b; } inline int max(int x,int y){ if(x>y) return x; return y; } inline int min(int x,int y){ if(x<y) return x; return y; } struct node{ int v,nex; }e[N*2]; inline void add(int u,int v){ cnt++; e[cnt].v=v; e[cnt].nex=head[u]; head[u]=cnt; } inline void dfs(int u,int fa){ dep[u]=dep[fa]+1; f[u][0]=fa; mx[u][0]=max(val[u],val[fa]); mn[u][0]=min(val[u],val[fa]); shun[u][0]=max(0,val[fa]-val[u]); dao[u][0]=max(0,val[u]-val[fa]); for(register int i=1;i<=20;++i){ f[u][i]=f[f[u][i-1]][i-1]; mx[u][i]=max(mx[u][i-1],mx[f[u][i-1]][i-1]); mn[u][i]=min(mn[u][i-1],mn[f[u][i-1]][i-1]); int k=mx[f[u][i-1]][i-1]-mn[u][i-1]; int p=mx[u][i-1]-mn[f[u][i-1]][i-1]; shun[u][i]=max(k,max(shun[u][i-1],shun[f[u][i-1]][i-1])); dao[u][i]=max(p,max(dao[u][i-1],dao[f[u][i-1]][i-1])); } for(register int i=head[u];i;i=e[i].nex){ int v=e[i].v; if(v==fa) continue; dfs(v,u); } } inline int lca(int a,int b){ int ans=0,Max=0,Min=0x3f3f3f3f; Max=val[b],Min=val[a]; if(dep[a]<dep[b]){ for(register int i=20;i>=0;--i){ if(dep[a]>dep[f[b][i]]) continue; ans=max(ans,max(Max-mn[b][i],dao[b][i])); Max=max(Max,mx[b][i]); b=f[b][i]; } } else{ for(register int i=20;i>=0;--i){ if(dep[b]>dep[f[a][i]]) continue; ans=max(ans,max(mx[a][i]-Min,shun[a][i])); Min=min(Min,mn[a][i]); a=f[a][i]; } } if(a==b) return ans; for(register int i=20;i>=0;--i){ if(f[b][i]==f[a][i]) continue; ans=max(ans,max(mx[a][i]-Min,shun[a][i])); ans=max(ans,max(Max-mn[b][i],dao[b][i])); Max=max(Max,mx[b][i]); Min=min(Min,mn[a][i]); a=f[a][i]; b=f[b][i]; } ans=max(ans,shun[a][0]); ans=max(ans,dao[b][0]); Max=max(Max,mx[b][0]); Min=min(Min,mn[a][0]); ans=max(ans,Max-Min); return ans; } int main(){ // freopen("1.in","r",stdin); // freopen("E.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&val[i]); } for(int i=1;i<n;++i){ scanf("%d%d",&a,&b); add(a,b);add(b,a); } dfs(1,0); scanf("%d",&q); for(int i=1;i<=q;++i){ scanf("%d%d",&a,&b); printf("%d\n",lca(a,b)); } getchar(); return 0; }
題解 【POJ3728】The merchant(LCA)