首页 > 代码库 > poj 3237 Tree
poj 3237 Tree
就是简单的树链剖分,但标记下传的时候一定要 ^1 而不能直接 = 1,我竟然WA在这么逗比的错误上不如一头撞死……
上代码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define N 1100000#define inf 0x7f7f7f7fusing namespace std;struct sss{ int minnum, maxnum; int push;}t[N*4];int n, nowplace, bianp[N];int p[N], next[N*2], v[N*2], c[N*2], bnum;int fa[N], son[N], siz[N], deep[N], top[N], w[N];void build_tree(int now, int l, int r){ t[now].minnum = inf; t[now].maxnum = -inf; t[now].push = 0; if (l == r) return; int mid = (l+r)/2; build_tree(now*2, l, mid); build_tree(now*2+1, mid+1, r);}void downdate(int now){ if (!t[now].push) return; t[now].push = 0; t[now*2].push ^= 1; t[now*2+1].push ^= 1; swap(t[now*2].maxnum, t[now*2].minnum); swap(t[now*2+1].maxnum, t[now*2+1].minnum); t[now*2].maxnum *= -1; t[now*2].minnum *= -1; t[now*2+1].maxnum *= -1; t[now*2+1].minnum *= -1;}void update(int now){ t[now].maxnum = max(t[now*2].maxnum, t[now*2+1].maxnum); t[now].minnum = min(t[now*2].minnum, t[now*2+1].minnum);}void addbian(int x, int y){ bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y; bnum++; next[bnum] = p[y]; p[y] = bnum; v[bnum] = x;}void dfs_1(int now, int nowfa, int nowdeep){ int k = p[now]; fa[now] = nowfa; deep[now] = nowdeep; int maxson = 0; son[now] = 0; siz[now] = 1; while (k) { if (v[k] != nowfa) { bianp[(k+1)/2] = v[k]; dfs_1(v[k], now, nowdeep+1); siz[now] += siz[v[k]]; if (siz[v[k]] > maxson) { maxson = siz[v[k]]; son[now] = v[k]; } } k = next[k]; }}void dfs_2(int now, int nowfa, int nowtop){ int k = p[now]; top[now] = nowtop; w[now] = ++nowplace; if (son[now]) dfs_2(son[now], now, nowtop); while (k) { if (v[k] != nowfa && v[k] != son[now]) dfs_2(v[k], now, v[k]); k = next[k]; }}int task(int now, int l, int r, int al, int ar){ if (al <= l && r <= ar) return t[now].maxnum; int mid = (l+r)/2, ans = -inf; downdate(now); if (al <= mid) ans = task(now*2, l, mid, al, ar); if (ar > mid) ans = max(ans, task(now*2+1, mid+1, r, al, ar)); update(now); return ans;}void tneg(int now, int l, int r, int tl, int tr){ if (tl <= l && r <= tr) { downdate(now); swap(t[now].maxnum, t[now].minnum); t[now].maxnum *= -1; t[now].minnum *= -1; t[now].push ^= 1; return; } int mid = (l+r)/2; downdate(now); if (tl <= mid) tneg(now*2, l, mid, tl, tr); if (tr > mid) tneg(now*2+1, mid+1, r, tl, tr); update(now); return;}void chan(int now, int l, int r, int cplace, int cnum){ if (l == r) { t[now].maxnum = t[now].minnum = cnum; return; } int mid = (l+r)/2; downdate(now); if (cplace <= mid) chan(now*2, l, mid, cplace, cnum); else chan(now*2+1, mid+1, r, cplace, cnum); update(now); return;}void neg(int u, int v){ int f1 = top[u], f2 = top[v]; if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } if (f1 == f2) { if (u == v) return; if (w[u] > w[v]) swap(u, v); tneg(1, 1, n, w[son[u]], w[v]); return; } tneg(1, 1, n, w[f1], w[u]); neg(fa[f1], v);}int find(int u, int v){ int f1 = top[u],f2 = top[v]; if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } if (f1 == f2) { if (u == v) return -inf; if (w[u] > w[v]) swap(u, v); return task(1, 1, n, w[son[u]], w[v]); } int ans = task(1, 1, n, w[f1], w[u]); return max(ans, find(fa[f1], v));}int main(){ int T; scanf("%d", &T); while (T--) { scanf("%d", &n); memset(p, 0, sizeof(p)); build_tree(1, 1, n); nowplace = 0; bnum = 0; for (int i = 1; i < n; ++i) { int x, y, z; scanf("%d%d%d", &x, &y, &z); addbian(x, y); c[i] = z; } dfs_1(1, 0, 1); dfs_2(1, 0, 1); for (int i = 1; i < n; ++i) chan(1, 1, n, w[bianp[i]], c[i]); char s[8]; while (scanf("%s", s) != EOF) { if (s[0] == ‘D‘) break; int x, y; scanf("%d%d", &x, &y); if (s[0] == ‘Q‘) printf("%d\n", find(x, y)); else if (s[0] == ‘C‘) chan(1, 1, n, w[bianp[x]], y); else if (s[0]==‘N‘) neg(x, y); } } return 0;}
poj 3237 Tree
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。