树链剖分
来源:互联网 发布:淘宝评价好评怎么修改 编辑:程序博客网 时间:2024/06/05 14:58
1、HDU 5052 Yaoge’s maximum profit
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <bitset>#include <ctime>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define lson low, mid, _id<<1#define rson mid+1, high, _id<<1|1typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;typedef pair<int, int> Pair;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 5e4 + 10;int T, N, Q, X, Y, Z, edge, id_count;int W[maxn], depth[maxn], son[maxn], top[maxn], size[maxn], father[maxn], id[maxn], key[maxn];int head[maxn], Next[2*maxn], to[2*maxn];ll lans[4*maxn], rans[4*maxn], lazy[4*maxn], Max[4*maxn], Min[4*maxn];void Init(void);void add_edge(int u, int v);void dfs_first(int u, int _father, int _depth);void dfs_second(int u, int _top);void build(int low, int high, int _id);void push_up(int _id);void update(int Left, int Right, ll val, int low, int high, int _id);void push_down(int _id);void Update(int u, int v, ll val);ll slove(int u, int v);ll query(int Left, int Right, int is_left, ll& max_price, ll& min_price, int low, int high, int _id);int main(){#ifdef __AiR_H freopen("in.txt", "r", stdin);#endif // __AiR_H scanf("%d", &T); while (T--) { scanf("%d", &N); Init(); for (int i = 1; i <= N; ++i) { scanf("%d", &W[i]); } for (int i = 1; i < N; ++i) { scanf("%d %d", &X, &Y); add_edge(X, Y), add_edge(Y, X); } dfs_first(1, 0, 1); dfs_second(1, 1); build(1, N, 1); scanf("%d", &Q); while (Q--) { scanf("%d %d %d", &X, &Y, &Z); printf("%I64d\n", slove(X, Y)); Update(X, Y, Z); } } return 0;}ll slove(int u, int v){ ll ans = 0, max_now_left, min_now_left, max_now_right, min_now_right; ll max_pre_left = 0, min_pre_left = Max[1], max_pre_right = 0, min_pre_right = Max[1]; while (top[u] != top[v]) { if (depth[top[u]] > depth[top[v]]) { ans = max(ans, query(id[top[u]], id[u], 1, max_now_left, min_now_left, 1, N, 1)); ans = max(ans, max_now_left - min_pre_left); ans = max(ans, max_pre_right - min_now_left); max_pre_left = max(max_pre_left, max_now_left); min_pre_left = min(min_pre_left, min_now_left); u = father[top[u]]; } else { ans = max(ans, query(id[top[v]], id[v], 0, max_now_right, min_now_right, 1, N, 1)); ans = max(ans, max_pre_right - min_now_right); ans = max(ans, max_now_right - min_pre_left); max_pre_right = max(max_pre_right, max_now_right); min_pre_right = min(min_pre_right, min_now_right); v = father[top[v]]; } } if (depth[u] > depth[v]) { ans = max(ans, query(id[v], id[u], 1, max_now_left, min_now_left, 1, N, 1)); ans = max(ans, max_now_left - min_pre_left); min_pre_left = min(min_pre_left, min_now_left); ans = max(ans, max_pre_right - min_pre_left); } else { ans = max(ans, query(id[u], id[v], 0, max_now_right, min_now_right, 1, N, 1)); ans = max(ans, max_pre_right - min_now_right); max_pre_right = max(max_pre_right, max_now_right); ans = max(ans, max_pre_right - min_pre_left); } return ans;}ll query(int Left, int Right, int is_left, ll& max_price, ll& min_price, int low, int high, int _id){ if (low == Left && high == Right) { max_price = Max[_id], min_price = Min[_id]; if (is_left) { return lans[_id]; } else { return rans[_id]; } } push_down(_id); int mid = (low + high) >> 1; if (Right <= mid) { return query(Left, Right, is_left, max_price, min_price, lson); } else if (Left > mid) { return query(Left, Right, is_left, max_price, min_price, rson); } else { ll ans_t, max_left, max_right, min_left, min_right; ll ans = max(query(Left, mid, is_left, max_left, min_left, lson), query(mid+1, Right, is_left, max_right, min_right, rson)); if (is_left) { ans_t = max_left - min_right; } else { ans_t = max_right - min_left; } max_price = max(max_left, max_right), min_price = min(min_left, min_right); ans_t = max(ans_t, 0ll), ans = max(ans, ans_t); return ans; }}void Update(int u, int v, ll val){ while (top[u] != top[v]) { if (depth[top[u]] < depth[top[v]]) { swap(u, v); } update(id[top[u]], id[u], val, 1, N, 1); u = father[top[u]]; } if (depth[u] > depth[v]) { swap(u, v); } update(id[u], id[v], val, 1, N, 1);}void update(int Left, int Right, ll val, int low, int high, int _id){ if (low == Left && high == Right) { Max[_id] += val, Min[_id] += val, lazy[_id] += val; return; } push_down(_id); int mid = (low + high) >> 1; if (Right <= mid) { update(Left, Right, val, lson); } else if (Left > mid) { update(Left, Right, val, rson); } else { update(Left, mid, val, lson), update(mid+1, Right, val, rson); } push_up(_id);}void push_down(int _id){ if (lazy[_id]) { Max[_id<<1] += lazy[_id], Min[_id<<1] += lazy[_id], lazy[_id<<1] += lazy[_id]; Max[_id<<1|1] += lazy[_id], Min[_id<<1|1] += lazy[_id], lazy[_id<<1|1] += lazy[_id]; lazy[_id] = 0; }}void build(int low, int high, int _id){ lazy[_id] = lans[_id] = rans[_id] = 0; if (low == high) { Max[_id] = Min[_id] = W[key[low]]; return; } int mid = (low + high) >> 1; build(lson), build(rson); push_up(_id);}void push_up(int _id){ Max[_id] = max(Max[_id<<1], Max[_id<<1|1]), Min[_id] = min(Min[_id<<1], Min[_id<<1|1]); lans[_id] = max(Max[_id<<1] - Min[_id<<1|1], max(lans[_id<<1], lans[_id<<1|1])); rans[_id] = max(Max[_id<<1|1] - Min[_id<<1], max(rans[_id<<1], rans[_id<<1|1])); if (lans[_id] < 0) { lans[_id] = 0; } if (rans[_id] < 0) { rans[_id] = 0; }}void dfs_second(int u, int _top){top[u] = _top;id[u] = ++id_count;key[id[u]] = u;if (son[u] == -1) {return;}dfs_second(son[u], _top);for (int i = head[u]; ~i; i = Next[i]) {int v = to[i];if (v != son[u] && v != father[u]) {dfs_second(v, v);}}}void dfs_first(int u, int _father, int _depth){depth[u] = _depth, father[u] = _father, size[u] = 1;for (int i = head[u]; ~i; i = Next[i]) {int v = to[i];if (v != _father) {dfs_first(v, u, _depth+1);size[u] += size[v];if (son[u] == -1 || size[v] > size[son[u]]) {son[u] = v;}}}}void add_edge(int u, int v){to[edge] = v, Next[edge] = head[u], head[u] = edge++;}void Init(void){memset(head, -1, sizeof(head));memset(son, -1, sizeof(son));edge = id_count = 0;}
0 0
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- 树链剖分
- android 在布局中使用自定义属性
- 设计模式学习1-工厂方法模式
- undefined和null的区别
- ABAP WORKFLOW工作流创建(一)
- AndroidStudio gradle配置
- 树链剖分
- Xcode常用快捷键
- 小程序WXML之数据绑定
- 多线程之Runnable
- uboot之start_armboot分析1
- 二叉树的递归和非递归遍历
- popupwindow的封装
- Realm 入门 简单实用方法
- JS垫脚石-字符串篇