(WWWWWWWWWW)codevs 3305 水果姐逛水果街Ⅱ
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(WWWWWWWWWW)codevs 3305 水果姐逛水果街Ⅱ相关的知识,希望对你有一定的参考价值。
写这么长了不A有点舍不得。。
想A又调不出来。。
于是乎就存一下..
#include <cstdio> #include <vector> #define N 205000 using namespace std; vector<int>Graph[N]; int max(int a,int b) {return a>b?a:b;} int min(int a,int b) {return a>b?b:a;} int Pri[N],n,m,dep[N],dad[N][25],Max[N][25],Min[N][25],up[N][25],down[N][25]; void dfs(int x) { dep[x]=dep[dad[x][0]]+1; for(int i=0;dad[x][i];++i) { Max[x][i+1]=max(Max[x][i],Max[dad[x][i]][i]); Min[x][i+1]=min(Min[x][i],Min[dad[x][i]][i]); up[x][i+1]=max(up[x][i],Max[dad[x][i]][i]-Min[x][i]); up[x][i+1]=max(up[x][i],up[dad[x][i]][i]); down[x][i+1]=max(down[x][i],down[dad[x][i]][i]); down[x][i+1]=max(down[x][i],Max[x][i]-Min[dad[x][i]][i]); dad[x][i+1]=dad[dad[x][i]][i]; } for(int i=0;i<Graph[x].size();++i) { int v=Graph[x][i]; if(dad[x][0]!=v) { dad[v][0]=x; Max[v][0]=max(Pri[x],Pri[v]); Min[v][0]=min(Pri[x],Pri[v]); up[v][0]=max(0,Pri[x]-Pri[v]); down[v][0]=min(0,Pri[v]-Pri[x]); dfs(v); } } } int lca(int x,int y) { if(dep[x]>dep[y]) swap(x,y); for(int i=20;i>=0;--i) if(dep[dad[y][i]]>=dep[x]) y=dad[y][i]; if(x==y) return x; for(int i=20;i>=0;--i) if(dad[y][i]!=dad[x][i]) x=dad[x][i],y=dad[y][i]; return dad[x][0]; } int Up(int x,int y) { int ret=0,Minn=0x7fffffff; if(dep[x]>dep[y]) swap(x,y); for(int i=20;i>=0;--i) { if(dep[dad[y][i]]>=dep[x]) { ret=max(ret,up[y][i]); ret=max(ret,Max[y][i]-Minn); Minn=min(Minn,Min[y][i]); y=dad[y][i]; } } if(x==y) return ret; for(int i=20;i>=0;--i) { if(dad[y][i]!=dad[x][i]) { ret=max(ret,max(up[y][i],up[x][i])); ret=max(ret,max(Max[y][i]-Minn,Max[x][i]-Minn)); Minn=min(Minn,min(Min[y][i],Min[x][i])); y=dad[y][i]; x=dad[x][i]; } } return ret; } int Down(int x,int y) { int ret=0,Maxn=0; if(dep[x]>dep[y]) swap(x,y); for(int i=20;i>=0;--i) { if(dep[dad[y][i]]>=dep[x]) { ret=min(ret,down[y][i]); ret=min(ret,Maxn-Min[y][i]); Maxn=max(Maxn,Max[y][i]); y=dad[y][i]; } } if(x==y) return ret; for(int i=20;i>=0;--i) { if(dad[y][i]!=dad[x][i]) { ret=min(ret,min(down[y][i],down[x][i])); ret=min(ret,min(Maxn-Min[y][i],Maxn-Min[x][i])); Maxn=max(Maxn,max(Max[y][i],Max[x][i])); y=dad[y][i]; x=dad[x][i]; } } return ret; } int query_max(int x,int y) { if(dep[x]>dep[y]) swap(x,y); int ret=Pri[y]; for(int i=20;i>=0;--i) { if(dep[dad[y][i]]>=dep[x]) { ret=max(ret,Max[y][i]); y=dad[y][i]; } } if(x==y) return ret; for(int i=20;i>=0;--i) { if(dad[y][i]!=dad[x][i]) { ret=max(ret,Max[x][i]); ret=max(ret,Max[y][i]); x=dad[x][i]; y=dad[y][i]; } } return ret; } int query_min(int x,int y) { if(dep[x]>dep[y]) swap(x,y); int ret=Pri[y]; for(int i=20;i>=0;--i) { if(dep[dad[y][i]]>=dep[x]) { ret=min(ret,Min[y][i]); y=dad[y][i]; } } if(x==y) return ret; for(int i=20;i>=0;--i) { if(dad[y][i]!=dad[x][i]) { ret=min(ret,Min[x][i]); ret=min(ret,Min[y][i]); x=dad[x][i]; y=dad[y][i]; } } return ret; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&Pri[i]); for(int x,y,i=1;i<n;++i) { scanf("%d%d",&x,&y); Graph[x].push_back(y); Graph[y].push_back(x); } dfs(1); scanf("%d",&m); for(int x,y;m--;) { scanf("%d%d",&x,&y); if(x==y) {puts("0");continue;} int z=lca(x,y),ans=0; ans=max(ans,Up(x,z)); ans=max(ans,Down(y,z)); ans=max(ans,query_max(x,z)-query_min(y,z)); printf("%d\n",ans); } return 0; }
以上是关于(WWWWWWWWWW)codevs 3305 水果姐逛水果街Ⅱ的主要内容,如果未能解决你的问题,请参考以下文章