hdoj 5052 Yaoge’s maximum profit 【树链剖分】
来源:互联网 发布:js实现bind 编辑:程序博客网 时间:2024/05/16 06:24
Yaoge’s maximum profit
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 870 Accepted Submission(s): 244
Problem Description
Yaoge likes to eat chicken chops late at night. Yaoge has eaten too many chicken chops, so that Yaoge knows the pattern in the world of chicken chops. There are N cities in the world numbered from 1 to N . There are some roads between some cities, and there is one and only one simple path between each pair of cities, i.e. the cities are connected like a tree. When Yaoge moves along a path, Yaoge can choose one city to buy ONE chicken chop and sell it in a city after the city Yaoge buy it. So Yaoge can get profit if Yaoge sell the chicken chop with higher price. Yaoge is famous in the world. AFTER Yaoge has completed one travel, the price of the chicken chop in each city on that travel path will be increased by V .
Input
The first line contains an integer T (0 < T ≤ 10), the number of test cases you need to solve. For each test case, the first line contains an integer N (0 < N ≤ 50000), the number of cities. For each of the next N lines, the i-th line contains an integer Wi(0 < Wi ≤ 10000), the price of the chicken chop in city i. Each of the next N - 1 lines contains two integers X Y (1 ≤ X, Y ≤ N ), describing a road between city X and city Y . The next line contains an integer Q(0 ≤ Q ≤ 50000), the number of queries. Each of the next Q lines contains three integer X Y V(1 ≤ X, Y ≤ N ; 0 < V ≤ 10000), meaning that Yaoge moves along the path from city X to city Y , and the price of the chicken chop in each city on the path will be increased by V AFTER Yaoge has completed this travel.
Output
For each query, output the maximum profit Yaoge can get. If no positive profit can be earned, output 0 instead.
Sample Input
15123451 22 33 44 551 5 15 1 11 1 25 1 11 2 1
Sample Output
40010
SB,线段树区间更新,写成单点更新了。T成狗了。 o(╯□╰)o
题意:给定n个鸡排店以及每个店鸡排的单价,有n-1条路连通所有的店。现在有Q次查询,x y z表示查询从x->y路径上可以获取的最大利润,你需要在第i个店买一个鸡排,在第j个店卖出,要求x -> i - > ... -> j -> y,其中i和j是可以相等的。走过x -> y的路径后,该路径上所有店的单价会升高z。
思路:在链上线段树维护区间最大值Max 最小值Min 往返最大利润best[2]。在沿着链找最大利润有点坑,考虑的情况有点多。
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#include <string>#define INF 0x3f3f3f3f#define eps 1e-8#define MAXN (50000+10)#define MAXM (300000+10)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while((a)--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1#define PI acos(-1.0)#pragma comment(linker, "/STACK:102400000,102400000")#define fi first#define se secondusing namespace std;struct Tree{ int l, r, Min, Max, lazy, len, best[2];};Tree tree[MAXN<<2];void PushUp(int o){ tree[o].Max = max(tree[ll].Max, tree[rr].Max); tree[o].Min = min(tree[ll].Min, tree[rr].Min); tree[o].best[0] = max(tree[ll].best[0], tree[rr].best[0]); tree[o].best[0] = max(tree[o].best[0], tree[rr].Max - tree[ll].Min); tree[o].best[1] = max(tree[ll].best[1], tree[rr].best[1]); tree[o].best[1] = max(tree[o].best[1], tree[ll].Max - tree[rr].Min);}void PushDown(int o){ if(tree[o].lazy) { tree[ll].lazy += tree[o].lazy; tree[rr].lazy += tree[o].lazy; tree[ll].Max += tree[o].lazy; tree[ll].Min += tree[o].lazy; tree[rr].Min += tree[o].lazy; tree[rr].Max += tree[o].lazy; tree[o].lazy = 0; }}int a[MAXN], pedge[MAXN];void Build(int o, int l, int r){ tree[o].l = l; tree[o].r = r; tree[o].lazy = tree[o].best[0] = tree[o].best[1] = 0; tree[o].len = r - l + 1; if(l == r) { tree[o].Min = tree[o].Max = a[pedge[l]]; return ; } int mid = (l + r) >> 1; Build(lson); Build(rson); PushUp(o);}void Update(int o, int L, int R, int v){ if(tree[o].l == L && tree[o].r == R) { tree[o].lazy += v; tree[o].Min += v; tree[o].Max += v; return ; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) Update(ll, L, R, v); else if(L > mid) Update(rr, L, R, v); else {Update(ll, L, mid, v); Update(rr, mid+1, R, v);} PushUp(o);}int Query(int o, int L, int R, int &Min, int &Max, int op){ if(tree[o].l == L && tree[o].r == R) { Min = tree[o].Min; Max = tree[o].Max; return tree[o].best[op]; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) return Query(ll, L, R, Min, Max, op); else if(L > mid) return Query(rr, L, R, Min, Max, op); else { int lMin, lMax, rMin, rMax; int ans = max(Query(ll, L, mid, lMin, lMax, op), Query(rr, mid+1, R, rMin, rMax, op)); Min = min(lMin, rMin); Max = max(lMax, rMax); if(op == 0) ans = max(ans, rMax - lMin); else ans = max(ans, lMax - rMin); return ans; }}struct Edge{ int to, next;};Edge edge[MAXN<<1];int head[MAXN], edgenum;void init(){ edgenum = 0; CLR(head, -1);}void addEdge(int u, int v){ edge[edgenum].to = v; edge[edgenum].next = head[u]; head[u] = edgenum++;}int son[MAXN], num[MAXN];int top[MAXN], pos[MAXN], id;int dep[MAXN], pre[MAXN];void DFS1(int u, int fa, int d){ dep[u] = d; pre[u] = fa; num[u] = 1; son[u] = -1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa) continue; DFS1(v, u, d+1); num[u] += num[v]; if(son[u] == -1 || num[son[u]] < num[v]) son[u] = v; }}void DFS2(int u, int T){ top[u] = T; pos[u] = ++id; pedge[id] = u; if(son[u] == -1) return ; DFS2(son[u], T); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == pre[u] || v == son[u]) continue; DFS2(v, v); }}int Get(int u, int v){ int f1 = top[u], f2 = top[v]; int ans = 0, lMin = INF, rMin = INF, lMax = 0, rMax = 0; int nowMax, nowMin; while(f1 != f2) { if(dep[f1] < dep[f2]) { ans = max(ans, Query(1, pos[f2], pos[v], nowMin, nowMax, 0)); ans = max(ans, rMax - nowMin); rMax = max(rMax, nowMax); rMin = min(rMin, nowMin); v = pre[f2], f2 = top[v]; //Update(1, pos[f2], pos[v], z); } else { ans = max(ans, Query(1, pos[f1], pos[u], nowMin, nowMax, 1)); ans = max(ans, nowMax - lMin); lMax = max(lMax, nowMax); lMin = min(lMin, nowMin); u = pre[f1], f1 = top[u]; //Update(1, pos[f1], pos[u], z); } } if(dep[u] < dep[v]) { ans = max(ans, Query(1, pos[u], pos[v], nowMin, nowMax, 0)); //Update(1, pos[u], pos[v], z); } else { ans = max(ans, Query(1, pos[v], pos[u], nowMin, nowMax, 1)); //Update(1, pos[v], pos[u], z); } ans = max(ans, rMax - nowMin); ans = max(ans, nowMax - lMin); ans = max(ans, rMax - lMin); return ans;}void Change(int u, int v, int z){ int f1 = top[u], f2 = top[v]; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(u, v); swap(f1, f2); } Update(1, pos[f1], pos[u], z); u = pre[f1], f1 = top[u]; } if(dep[u] > dep[v]) swap(u, v); Update(1, pos[u], pos[v], z);}int main(){ int t; Ri(t); W(t) { int n; Ri(n); init(); for(int i = 1; i <= n; i++) Ri(a[i]); for(int i = 1; i <= n-1; i++) { int s, e; Ri(s); Ri(e); addEdge(s, e); addEdge(e, s); } DFS1(1, -1, 1); id = 0; DFS2(1, 1); Build(1, 1, id); int Q; Ri(Q); while(Q--) { int x, y, z; Ri(x); Ri(y); Ri(z); Pi(Get(x, y)); Change(x, y, z); } } return 0;}
0 0
- hdoj 5052 Yaoge’s maximum profit 【树链剖分】
- hdu 5052 Yaoge’s maximum profit(树链剖分)
- 【HDU】5052 Yaoge’s maximum profit 树链剖分
- Hdu 5052 Yaoge’s maximum profit(树链剖分)
- HDU 5052 Yaoge’s maximum profit (树链剖分 + 线段树)
- hdu 5052 Yaoge’s maximum profit
- 【HDU 5052】Yaoge’s maximum profit【树链刨分】
- hdu5052 Yaoge’s maximum profit 树链剖分
- hdu5052 Yaoge’s maximum profit (树链剖分)
- HDU 5052 Yaoge’s maximum profit(树链剖分+线段树,2014上海网络赛1011)
- hdu 5052 Yaoge’s maximum profit 树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
- HDU 5052 Yaoge’s maximum profit(树链剖分——点权,区间合并)
- HDU 5052 Yaoge’s maximum profit 裸树链剖分 2014 ACM/ICPC Asia Regional Shanghai Online
- Hdu 5052 Yaoge’s maximum profit 动态树 LCT link-cut tree
- HDU5052 Yaoge’s maximum profit(树链剖分)点权更新,经典题
- Maximum Profit
- Aizu ALDS1_1_D Maximum Profit
- 第二章 ALDS1_1_D:Maximum Profit
- pixhawk学习笔记
- Simple Java—Strings and Arrays(三)为什么String被设计成了不可变型
- Error: must call SetScrollSizes() or SetScaleToFitSize()问题的解决
- iOS-如何在工程内添加pch预编译头文件
- 知识库
- hdoj 5052 Yaoge’s maximum profit 【树链剖分】
- Android 学习笔记(一)(客户端、服务器socket通信教程)
- Uva 1395
- MySQL Proxy
- pixhawk-----mavlink
- 捕获键盘中断
- <c:forEach varStatus="status">中 varStatus的属性简介
- spark transform系列__sample
- C#随机生成1到60不重复随机数