树链剖分 (LCT基础)

来源:互联网 发布:潍坊学院网络信息门户 编辑:程序博客网 时间:2024/05/21 03:26
#include <bits/stdc++.h>using namespace std;#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)#define RREP(i, a) for (int i = first[a]; i > 0; i = next[i])#define debug(...) fprintf(stderr,__VA_ARGS__)#define mp make_pair#define pb push_back#define SZ(x) (int((x).size() - 1))#define ALL(x) ((x).begin() + 1), (x).end()template<typename T> inline bool chkmin(T &a,const T &b){ return a > b ? a = b, 1 : 0; }template<typename T> inline bool chkmax(T &a,const T &b){ return a < b ? a = b, 1 : 0; }#define next Nexttypedef long long LL;const int dmax = 100100, oo = 0x3f3f3f3f;struct edge{int x, y, z;edge(){x = y = z = 0;}};edge tmp[dmax];int n, m, N = 0;int first[dmax], next[dmax], to[dmax], w[dmax], E;inline void Edge(int x, int y, int z){to[++E] = y;w[E] = z;next[E] = first[x];first[x] = E;}inline void Tmp(int x, int y, int z){tmp[E].x = x;tmp[E].y = y;tmp[E].z = z;}int a[dmax], d[dmax], pre[dmax], dis[dmax], top[dmax], size[dmax], rank[dmax], son[dmax];void dfs(int x, int fa, int dep){dis[x] = dep;pre[x] = fa;size[x] = 1;RREP(i, x){int y = to[i];if (y != fa){dfs(y, x, dep+1);size[x] += size[y];if (size[y] > size[son[x]])son[x] = y;}}}void dfs(int x, int index){d[x] = ++N;top[x] = index;if (son[x] > 0)dfs(son[x], index);RREP(i, x){int y = to[i];if (y != pre[x] && y != son[x])dfs(y, y);}}int c[dmax];inline int Mid(int x, int y){ return (x + y) >> 1; }inline void up(int x){ c[x] = max(c[x * 2], c[x * 2 + 1]); }void create(int x, int l, int r){int mid = Mid(l, r);if (l == r){c[x] = a[mid];return;}if (l <= mid)create(x * 2, l, mid);if (mid+1 <= r)create(x * 2 + 1, mid+1, r);up(x);}void update(int x, int l, int r, int y, int z){if (l == r){c[x] = z;return;}int mid = Mid(l, r);if (y <= mid)update(x * 2, l, mid, y, z);else update(x * 2 + 1, mid + 1, r, y, z);}int query(int x, int l, int r, int s, int t){if (l == s && r == t)return c[x];int mid = Mid(l, r);if (t <= mid)return query(x * 2, l, mid, s, t);else{if (s > mid)return query(x * 2 + 1, mid + 1, r, s, t);else{return max(query(x * 2, l, mid, s, mid),query(x * 2 + 1, mid + 1, r, mid + 1, t));}}}void change(int x, int y){if (dis[tmp[x].x] < dis[tmp[x].y])update(1, 2, n, d[tmp[x].y], y);else update(1, 2, n, d[tmp[x].x], y);}int cal(int x, int y){int ans = -oo;while (top[x] != top[y]){if (dis[top[x]] < dis[top[y]]) swap(x, y);chkmax(ans, query(1, 2, n, d[top[x]], d[x]));x = pre[top[x]];}if (dis[x] > dis[y]) swap(x, y);if (x != y)chkmax(ans, query(1, 2, n, d[x] + 1, d[y]));return ans;}int main(){#ifndef ONLINE_JUDGEfreopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);#endifscanf("%d", &n);REP(i, 1, n-1){int x, y, z;scanf("%d%d%d", &x, &y, &z);Edge(x, y, z);Tmp(x, y, z);}dfs(1, 1, 1);dfs(1, 1);REP(i, 1, n-1)if (dis[tmp[i].x] < dis[tmp[i].y])a[d[tmp[i].y]] = tmp[i].z;else a[d[tmp[i].x]] = tmp[i].z;create(1, 2, n);scanf("%d", &m);getchar();REP(i, 1, m){int q = getchar(), x, y;scanf("%d%d", &x, &y);getchar();if (q == 'Q')printf("%d\n", cal(x, y));else change(x, y);}return 0;}

0 0