Codevs 3305 水果姐逛水果街Ⅱ 倍增LCA
2016-03-14 14:57
417 查看
题目:http://codevs.cn/problem/3305/
时间限制: 2 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
题解
题目描述 Description
水果姐第二天心情也很不错,又来逛水果街。
突然,cgh又出现了。cgh施展了魔法,水果街变成了树结构(店与店之间只有一条唯一的路径)。
同样还是n家水果店,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样。
cgh给出m个问题,每个问题要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去。求最多可以赚多少钱。
水果姐向学过oi的你求助。
输入描述 Input Description
第一行n,表示有n家店
下来n个正整数,表示每家店一个苹果的价格。
下来n-1行,每行两个整数x,y,表示第x家店和第y家店有一条边。
下来一个整数m,表示下来有m个询问。
下来有m行,每行两个整数x和y,表示从第x家店出发到第y家店。
输出描述 Output Description
有m行。
每行对应一个询问,一个整数,表示面对cgh的每次询问,水果姐最多可以赚到多少钱。
样例输入 Sample Input
10
16 5 1 15 15 1 8 9 9 15
1 2
1 3
2 4
2 5
2 6
6 7
4 8
1 9
1 10
6
9 1
5 1
1 7
3 3
1 1
3 6
样例输出 Sample Output
7
11
7
0
0
15
数据范围及提示 Data Size & Hint
0<=苹果的价格<=10^8
0<n<=200000
0<m<=10000
题解:
和3304同理,改为树上倍增即可。
处理信息特别麻烦。。。
代码略丑。。。
View Code
时间限制: 2 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
题解
题目描述 Description
水果姐第二天心情也很不错,又来逛水果街。
突然,cgh又出现了。cgh施展了魔法,水果街变成了树结构(店与店之间只有一条唯一的路径)。
同样还是n家水果店,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样。
cgh给出m个问题,每个问题要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去。求最多可以赚多少钱。
水果姐向学过oi的你求助。
输入描述 Input Description
第一行n,表示有n家店
下来n个正整数,表示每家店一个苹果的价格。
下来n-1行,每行两个整数x,y,表示第x家店和第y家店有一条边。
下来一个整数m,表示下来有m个询问。
下来有m行,每行两个整数x和y,表示从第x家店出发到第y家店。
输出描述 Output Description
有m行。
每行对应一个询问,一个整数,表示面对cgh的每次询问,水果姐最多可以赚到多少钱。
样例输入 Sample Input
10
16 5 1 15 15 1 8 9 9 15
1 2
1 3
2 4
2 5
2 6
6 7
4 8
1 9
1 10
6
9 1
5 1
1 7
3 3
1 1
3 6
样例输出 Sample Output
7
11
7
0
0
15
数据范围及提示 Data Size & Hint
0<=苹果的价格<=10^8
0<n<=200000
0<m<=10000
题解:
和3304同理,改为树上倍增即可。
处理信息特别麻烦。。。
代码略丑。。。
#include<bits/stdc++.h> using namespace std; #define MAXN 200010 #define INF 1e9 struct node { int begin,end,next; }edge[MAXN*2]; int cnt,Head[MAXN],n,P[MAXN][18],mx[MAXN][18],mn[MAXN][18],lc[MAXN][18],rc[MAXN][18],deep[MAXN],a[MAXN]; bool vis[MAXN]; void addedge(int bb,int ee) { edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt; } void addedge1(int bb,int ee) { addedge(bb,ee);addedge(ee,bb); } int read() { int s=0,fh=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();} return s*fh; } void dfs1(int u) { int i,j,v; vis[u]=true; for(j=1;(1<<j)<=n;j++) { P[u][j]=P[P[u][j-1]][j-1]; mx[u][j]=max(mx[u][j-1],mx[P[u][j-1]][j-1]); mn[u][j]=min(mn[u][j-1],mn[P[u][j-1]][j-1]); lc[u][j]=max(lc[u][j-1],lc[P[u][j-1]][j-1]); lc[u][j]=max(lc[u][j],mx[P[u][j-1]][j-1]-mn[u][j-1]); rc[u][j]=max(rc[u][j-1],rc[P[u][j-1]][j-1]); rc[u][j]=max(rc[u][j],mx[u][j-1]-mn[P[u][j-1]][j-1]); } for(i=Head[u];i!=-1;i=edge[i].next) { v=edge[i].end; if(vis[v]==false) { deep[v]=deep[u]+1; P[v][0]=u; mx[v][0]=max(a[u],a[v]);//最大值 mn[v][0]=min(a[u],a[v]);//最小值 lc[v][0]=max(0,a[u]-a[v]);//从i点到达fa[i][j]点的最大利润. rc[v][0]=max(0,a[v]-a[u]);//从fa[i][j]点到达i点的最大利润. dfs1(v); } } } /*void Ycl() { int i,j; for(j=1;(1<<j)<=n;j++) { for(i=1;i<=n;i++) { if(P[i][j-1]!=-1) { P[i][j]=P[P[i][j-1]][j-1]; mx[i][j]=max(mx[i][j],max(mx[i][j-1],mx[P[i][j-1]][j-1])); mn[i][j]=min(mn[i][j],min(mn[i][j-1],mn[P[i][j-1]][j-1])); lc[i][j]=max(lc[i][j],max(lc[i][j-1],lc[P[i][j-1]][j-1])); lc[i][j]=max(lc[i][j],mx[P[i][j-1]][j-1]-mn[i][j-1]); rc[i][j]=max(rc[i][j],max(rc[i][j-1],rc[P[i][j-1]][j-1])); rc[i][j]=max(rc[i][j],mx[i][j-1]-mn[P[i][j-1]][j-1]); } } } }*/ int LCA(int x,int y) { int i,j; if(deep[x]<deep[y])swap(x,y); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j]; if(x==y)return x; for(j=i;j>=0;j--) { if(P[x][j]!=-1&&P[x][j]!=P[y][j]) { x=P[x][j]; y=P[y][j]; } } return P[x][0]; } int MAX1(int x,int y) { int i,j,maxv=-INF; if(deep[x]<deep[y])swap(x,y); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[y]) { maxv=max(maxv,lc[x][j]); x=P[x][j]; } } return maxv; } int MAX2(int x,int y) { int i,j,maxv=-INF; if(deep[x]<deep[y])swap(x,y); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[y]) { maxv=max(maxv,rc[x][j]); x=P[x][j]; } } return maxv; } int MX(int x,int y) { int i,j,maxv=-INF; if(deep[x]<deep[y])swap(x,y); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[y]) { maxv=max(maxv,mx[x][j]); x=P[x][j]; } } return maxv; } int MN(int x,int y) { int i,j,minv=INF; if(deep[x]<deep[y])swap(x,y); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[y]) { minv=min(minv,mn[x][j]); x=P[x][j]; } } return minv; } int Ask(int x,int y) { int lca=LCA(x,y),xx=x,yy=y,i,j; int maxxx=-INF,minnn=INF,ans=0; if(deep[x]<deep[lca])swap(x,lca); for(i=0;(1<<i)<=deep[x];i++);i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[lca]) { ans=max(ans,max(lc[x][j],mx[x][j]-minnn)); minnn=min(mn[x][j],minnn); x=P[x][j]; } } if(deep[y]<deep[lca])swap(y,lca); for(i=0;(1<<i)<=deep[y];i++);i--; for(j=i;j>=0;j--) { if(deep[y]-(1<<j)>=deep[lca]) { ans=max(ans,max(rc[y][j],maxxx-mn[y][j])); maxxx=max(mx[y][j],maxxx); y=P[y][j]; } } return max(ans,maxxx-minnn); } int main() { int bb,ee,i,j,m,x,y,ans,lca; n=read(); for(i=1;i<=n;i++)a[i]=read(); memset(Head,-1,sizeof(Head));cnt=1; for(i=1;i<n;i++) { bb=read();ee=read(); addedge1(bb,ee); } memset(P,-1,sizeof(P)); /*for(j=1;(1<<j)<=n;j++) { for(i=1;i<=n;i++) { mn[i][j]=0;mx[i][j]=0; lc[i][j]=rc[i][j]=0; } }*/ dfs1(1);//Ycl(); m=read(); for(i=1;i<=m;i++) { x=read();y=read(); if(x==y)printf("0\n"); else// if(x<y) { printf("%d\n",Ask(x,y)); //if(x>y)swap(x,y); /*lca=LCA(x,y); ans=0; ans=max(ans,MAX1(x,lca)); ans=max(ans,MAX2(lca,y)); ans=max(ans,MX(lca,y)-MN(x,lca)); printf("%d\n",ans);*/ } /*else { lca=LCA(x,y); ans=-INF; ans=max(ans,MAX1(x,lca)); ans=max(ans,MAX2(y,lca)); ans=max(ans,MX(y,lca)-MN(x,lca)); printf("%d\n",ans); }*/ } return 0; }
View Code
相关文章推荐
- mysql分区(partition)
- 自己定制Linux发行版(资料)
- 工作中常用Windows快捷键整理(1)-快速关闭网页
- Java 回顾笔记_多线程_线程通讯2
- Android应用签名
- fstab 文件作用
- 工作中常用Windows快捷键整理(1)-快速关闭网页
- TableView滚动时的懒加载
- web.xml中配置spring的几种方式
- Android SDK Samples,学习Android的好方法
- strcop(),strcmp(),strcat(),strstr(),strchr()实现
- java implement和extends
- devexpress停靠菜单
- Java反射Reflection
- invalidate()和requestLayout()区别
- 【SSH (七) 】使用ajax + json 交互
- Xcode中使用Scheme管理项目
- Web-Fontmin -- 在线提取你需要的字体
- 东北赛选拔教训
- 根据给定日期判断当天是星期几