1. 程式人生 > >CodeVs——T 3305 水果姐逛水果街Ⅱ

CodeVs——T 3305 水果姐逛水果街Ⅱ

pre targe mut log i++ lock ima deep 多少

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

維護樹上信息,包括 從兒子到自己的 最大值 最小值,從上到下的最優解,從下到上的最優解

倍增 LCA 向上完成信息的Up 真滴惡心

  1 #include <cstdio>
  2 
  3 using namespace
std; 4 5 const int INF(999999999); 6 const int N(200000+15); 7 int n,m,u,v,pri[N],ans; 8 9 int head[N],sumedge; 10 struct Edge 11 { 12 int v,next; 13 Edge(int v=0,int next=0): v(v),next(next){} 14 }edge[N<<1]; 15 void ins(int u,int v) 16 { 17 edge[++sumedge]=Edge(v,head[u]); 18 head[u]=sumedge; 19 } 20 21 #define swap(a,b) {int temp=a;a=b;b=temp;} 22 #define max(a,b) (a>b?a:b) 23 #define min(a,b) (a<b?a:b) 24 25 struct Node 26 { 27 int dad,maxx,minn,up_down,down_up; 28 }shop[N][25]; 29 int deep[N],maxx,minn,lca; 30 void DFS(int x,int fa) 31 { 32 deep[x]=deep[fa]+1; 33 shop[x][0].maxx=max(pri[x],pri[fa]); 34 shop[x][0].minn=min(pri[x],pri[fa]); 35 shop[x][0].down_up=max(0,pri[fa]-pri[x]); 36 shop[x][0].up_down=max(0,pri[x]-pri[fa]); 37 for(int i=1;shop[x][i-1].dad;i++) 38 { 39 shop[x][i].dad=shop[shop[x][i-1].dad][i-1].dad; 40 shop[x][i].maxx=max(shop[x][i-1].maxx,shop[shop[x][i-1].dad][i-1].maxx); 41 shop[x][i].minn=min(shop[x][i-1].minn,shop[shop[x][i-1].dad][i-1].minn); 42 shop[x][i].down_up=max(shop[x][i-1].down_up,shop[shop[x][i-1].dad][i-1].down_up); 43 shop[x][i].down_up=max(shop[x][i].down_up,shop[shop[x][i-1].dad][i-1].maxx-shop[x][i-1].minn); 44 shop[x][i].up_down=max(shop[x][i-1].up_down,shop[shop[x][i-1].dad][i-1].up_down); 45 shop[x][i].up_down=max(shop[x][i].up_down,shop[x][i-1].maxx-shop[shop[x][i-1].dad][i-1].minn); 46 } 47 for(int i=head[x];i;i=edge[i].next) 48 { 49 int v=edge[i].v; 50 if(shop[x][0].dad!=v) shop[v][0].dad=x,DFS(v,x); 51 } 52 } 53 54 int LCA(int x,int y) 55 { 56 if(deep[x]>deep[y]) swap(x,y); 57 for(int i=24;i>=0;i--) 58 if(deep[shop[y][i].dad]>=deep[x]) y=shop[y][i].dad; 59 if(x==y) return x; 60 for(int i=24;i>=0;i--) 61 if(shop[x][i].dad!=shop[y][i].dad) x=shop[x][i].dad,y=shop[y][i].dad; 62 return shop[x][0].dad; 63 } 64 /*Node Query(int u,int v) 65 { 66 Node ret; 67 ret.minn=1e9,ret.maxx=-23333,ret.up_down=-23333,ret.down_up=-23333; 68 for(int i=20;i>=0;i--) 69 if(deep[shop[u][i].dad]>=deep[v]) 70 { 71 ret.minn=min(shop[u][i].minn,ret.minn); 72 ret.maxx=max(shop[u][i].maxx,ret.maxx); 73 ret.up_down=max(ret.up_down,shop[u][i].maxx-ret.minn); 74 ret.down_up=max(ret.down_up,ret.maxx-shop[u][i].minn); 75 u=shop[u][i].dad; 76 } 77 minx=ret.minn; maxx=ret.maxx; 78 return ret; 79 }*/ 80 int Query(int u,int v) 81 { 82 ans=0; minn=INF;maxx=-INF; 83 lca=LCA(u,v); 84 int dep1=deep[u]-deep[lca]; 85 if(dep1>0) 86 for(int i=24;i>=0;i--) 87 if(dep1&(1<<i)) 88 { 89 ans=max(ans,max(shop[u][i].down_up,shop[u][i].maxx-minn)); 90 minn=min(minn,shop[u][i].minn); 91 u=shop[u][i].dad; 92 } 93 int dep2=deep[v]-deep[lca]; 94 if(dep2>0) 95 { 96 for(int i=24;i>=0;i--) 97 if(dep2&(1<<i)) 98 { 99 ans=max(ans,max(shop[v][i].up_down,maxx-shop[v][i].minn)); 100 maxx=max(maxx,shop[v][i].maxx); 101 v=shop[v][i].dad; 102 } 103 } 104 return max(ans,maxx-minn); 105 } 106 107 int main() 108 { 109 scanf("%d",&n); 110 for(int i=1;i<=n;i++) 111 scanf("%d",&pri[i]); 112 for(int i=1;i<n;i++) 113 { 114 scanf("%d%d",&u,&v); 115 ins(u,v); ins(v,u); 116 } 117 DFS(1,0); 118 scanf("%d",&m); 119 for(;m--;) 120 { 121 scanf("%d%d",&u,&v); 122 if(u==v) puts("0"); 123 else 124 { 125 /*minx=1e9,maxx=-1e9,ans=-2333333,lca=LCA(u,v); 126 int dep1=deep[u]-deep[lca]; 127 int dep2=deep[v]-deep[lca]; 128 if(dep1>0) ans=max(ans,Query(u,lca).down_up); 129 else ans=max(ans,Query(lca,u).up_down); 130 if(dep2>0) ans=max(ans,Query(v,lca).down_up); 131 else ans=max(ans,Query(lca,v).up_down); 132 ans=max(ans,maxx-minx);*/ 133 printf("%d\n",Query(u,v)); 134 } 135 } 136 return 0; 137 }

CodeVs——T 3305 水果姐逛水果街Ⅱ