【SPOJ】6779 Can you answer these queries VII
2012-08-30 00:10
441 查看
SPOJ……无力吐槽了,反正RP好的时候过了,其他时候都是TLE。
只能怪自己动态树太龊了吧。。
只能怪自己动态树太龊了吧。。
#include<cstdio> #include<cstring> #include<queue> #include<iostream> #define MAX(a,b) ((a)>(b)?(a):(b)) #define oo 0x7FFFFFFF #define MAXN 200010 using namespace std; bool vis[MAXN]; int e, first[MAXN], next[MAXN], v[MAXN]; struct LCT { int bef[MAXN]; int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN]; int left[MAXN], right[MAXN], sum[MAXN], val[MAXN], same[MAXN]; inline void PushUp(int x) { int L, R; L = next[x][0], R = next[x][1]; num[x] = num[L] + num[R] + 1; sum[x] = sum[L] + sum[R] + key[x]; left[x] = MAX(left[L],sum[L]+key[x]+left[R]); right[x] = MAX(right[R],sum[R]+key[x]+right[L]); val[x] = MAX(val[L],val[R]); val[x] = MAX(val[x],key[x]+right[L]+left[R]); } inline void Down(int x, int k) { if (x) { same[x] = key[x] = k; sum[x] = k * num[x]; left[x] = right[x] = val[x] = MAX(sum[x],0); } } inline void PushDown(int x) { if (same[x] != oo) { int L, R; L = next[x][0], R = next[x][1]; if (L) { same[L] = key[L] = same[x]; sum[L] = same[x] * num[L]; left[L] = right[L] = val[L] = MAX(sum[L],0); } if (R) { same[R] = key[R] = same[x]; sum[R] = same[x] * num[R]; left[R] = right[R] = val[R] = MAX(sum[R],0); } same[x] = oo; } } void Rotate(int x, int kind) { int y, z; y = pre[x]; z = pre[y]; PushDown(y); PushDown(x); next[y][!kind] = next[x][kind]; pre[next[x][kind]] = y; next[z][next[z][1] == y] = x; pre[x] = z; next[x][kind] = y; pre[y] = x; PushUp(y); } void Splay(int x) { int rt; for (rt = x; pre[rt]; rt = pre[rt]) ; if (rt != x) { bef[x] = bef[rt]; bef[rt] = 0; while (pre[x]) { if (next[pre[x]][0] == x) Rotate(x, 1); else Rotate(x, 0); } PushUp(x); } else PushDown(x); } void Access(int x) { int father; for (father = 0; x; x = bef[x]) { Splay(x); bef[next[x][1]] = x; pre[next[x][1]] = 0; next[x][1] = father; pre[father] = x; bef[father] = 0; father = x; PushUp(x); } } int Query(int x, int y) { int ans; Access(y); for (y = 0; x; x = bef[x]) { Splay(x); if (!bef[x]) { ans = MAX(val[y],val[next[x][1]]); ans = MAX(ans,key[x]+left[y]+left[next[x][1]]); return ans; } bef[next[x][1]] = x; pre[next[x][1]] = 0; next[x][1] = y; pre[y] = x; bef[y] = 0; y = x; PushUp(x); } return 0; } void Update(int x, int y, int price) { Access(y); for (y = 0; x; x = bef[x]) { Splay(x); if (!bef[x]) { key[x] = price; if (y) { same[y] = key[y] = price; sum[y] = price * num[y]; left[y] = right[y] = val[y] = MAX(price,0); } if (next[x][1]) { y = next[x][1]; same[y] = key[y] = price; sum[y] = price * num[y]; left[y] = right[y] = val[y] = MAX(price,0); } } bef[next[x][1]] = x; pre[next[x][1]] = 0; next[x][1] = y; pre[y] = x; bef[y] = 0; y = x; PushUp(x); } } } lct; inline void AddEdge(int x, int y) { v[e] = y; next[e] = first[x]; first[x] = e++; } void BFS(int x) { int i, y; queue<int> q; vis[x] = true; q.push(x); while (!q.empty()) { x = q.front(); q.pop(); for (i = first[x]; i != -1; i = next[i]) { y = v[i]; if (!vis[y]) { lct.same[y] = oo; lct.bef[y] = x; vis[y] = true; q.push(y); } } } } int INT() { int res; char ch; bool neg; while (ch = getchar_unlocked(), !isdigit(ch) && ch != '-') ; if (ch == '-') { res = 0; neg = true; } else { res = ch - '0'; neg = false; } while (ch = getchar_unlocked(), isdigit(ch)) res = res * 10 + ch - '0'; return neg ? -res : res; } int main() { int n, i, q, cmd, x, y, val; n = INT(); for (i = 1; i <= n; i++) { lct.key[i] = INT(); lct.same[i] = oo; } memset(first, -1, sizeof(first)); for (e = 0, i = 1; i < n; i++) { x = INT(), y = INT(); AddEdge(x, y); AddEdge(y, x); } BFS(1); scanf("%d", &q); while (q--) { cmd = INT(), x = INT(), y = INT(); if (cmd == 1) printf("%d\n", lct.Query(x, y)); else { val = INT(); lct.Update(x, y, val); } } return 0; }
相关文章推荐
- Spoj 6779 Can you answer these queries VII 树链剖分 在树上任意路径的最大子段和 区间修改点权
- 【SPOJ】6779 Can you answer these queries VII 树链剖分+线段树 求树上的最大子段和
- 6779. Can you answer these queries VII - SPOJ
- SPOJ 6779 Can you answer these queries VII 树链剖分
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
- SPOJ 6779 Can you answer these queries VII(动态树)
- 动态树LCT(SPOJ 6779 Can you answer these queries VII)
- SPOJ 6779 Can you answer these queries VII
- spoj 6779. Can you answer these queries VII(树链剖分)
- SPOJ GSS7: Can you answer these queries VII 题解
- SPOJ-GSS7 Can you answer these queries VII(树上区间最大和)
- SPOJGSS7 Can you answer these queries VII
- SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树
- SPOJ GSS7 Can you answer these queries VII(LCT)
- spoj 1043 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III
- 【SPOJ】1043 Can you answer these queries III
- SPOJ 1716 Can you answer these queries III(GSS3 线段树)
- 【SPOJ】1716 Can you answer these queries III 线段树
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字