树链剖分。。。
375. Query on a treeProblem code: QTREE |
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
<pre name="code" class="cpp">#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N = 100100; #define prt(k) cout<<#k" = "<<k<<endl; struct Edge { int to, next; }e[N<<2]; int head[N], Size; void init_edge() { memset(head, -1, sizeof head); Size = 0; } void addedge(int u, int v) { e[Size] = (Edge) {v, head[u]}; head[u] = Size++; } int siz[N], dep[N], fa[N], top[N], son[N], p[N]; int n; void dfs1(int u, int pre, int d) { siz[u] = 1; fa[u] = pre; dep[u] = d; for(int i=head[u];~i;i=e[i].next) { int v = e[i].to; if(v == pre) continue; dfs1(v, u, d + 1); siz[u] += siz[v]; if(son[u]==-1 || siz[son[u]] < siz[v]) son[u] = v; } } int pos; void getPOS(int u, int to) { top[u] = to; p[u] = pos++; if(~son[u]) getPOS(son[u], to); for(int i=head[u];~i;i=e[i].next) { int v = e[i].to; if(v-fa[u] && v-son[u]) getPOS(v, v); } } void init() { memset(son, -1, sizeof son); init_edge(); pos = 0; } /***********Tree*************/ int tree[N<<2]; #define ls o*2 #define rs o*2+1 #define lson l,m,ls #define rson m+1,r,rs void build(int l,int r,int o) { tree[o] = 0; if(l==r) return ; int m = (l+r) /2; build(lson); build(rson); } void pushup(int o) { tree[o] = max(tree[ls], tree[rs]); } void update(int pos, int val, int l=1, int r=n, int o=1) { if(l==r) { if(l==pos) tree[o] = val; return; } int m = (l+r)/2; if(pos<=m) update(pos, val, lson); else update(pos, val, rson); pushup(o); } int query(int L, int R, int l,int r, int o) { if(L<=l && r<=R) return tree[o]; int m = (l+r)/ 2; int res=0; if(L<=m) res=max(res, query(L,R,lson)); if(m<R) res=max(res,query(L,R,rson)); return res; } inline int query(int L, int R) { // if(L>R) swap(L, R); if(L<1) L = 1; return query(L,R, 1,n,1); } /*********End Tree*************/ inline int find(int u, int v) { int f1 = top[u], f2 = top[v], tmp = 0; while(f1 - f2) { if(dep[f1] < dep[f2]) swap(f1, f2), swap(u,v); tmp = max(tmp, query(p[f1], p[u])); u = fa[f1]; f1 = top[u]; // cout<<u<<endl; } if(u==v) return tmp; if(dep[u] > dep[v]) swap(u, v); return max(tmp, query(p[son[u]], p[v])); } int g[N][3]; inline void read(int &a) { char c = 0; while(!isdigit(c)) c=getchar(); a = 0; while(isdigit(c)) a = a * 10 + c - '0', c = getchar(); } void show(int l ,int r, int o) { printf("[%d, %d] : tree[%d] = %d\n", l, r, o, tree[o]); if(l==r) return; int m = (l+r) / 2; show(lson); show(rson); if(o==1) putchar(10); } int main() { // int a,b; read(a); read(b); cout<<a<<' '<<b<<endl; // freopen("qtree.in", "r", stdin); int T; scanf("%d", &T); while(T--) { scanf("%d", &n); n--; init(); for(int i=1;i<=n;i++) { int a,b,c; read(a); read(b); read(c); // scanf("%d%d%d", &a, &b, &c); g[i][0]=a, g[i][1]=b, g[i][2]=c; addedge(a,b); addedge(b,a); } dfs1(1, 1, 0); getPOS(1, 1); build(1, n, 1); for(int i=1;i<=n;i++) { if(dep[g[i][0]] > dep[g[i][1]]) swap(g[i][0], g[i][1]); // cout<<p[g[i][1]]<< ' '<< g[i][1]<<endl; update(p[g[i][1]], g[i][2]); // prt(p[g[i][1]]); prt(g[i][2]); } char op[11]; while(scanf("%s", op)==1) { if(op[0]=='Q') { int a, b; //scanf("%d%d", &a, &b); read(a); read(b); // show(1, n, 1); printf("%d\n", find(a,b)); } else if(op[0]=='C') { int a,b; //scanf("%d%d", &a, &b); read(a); read(b); update(p[g[a][1]], b, 1, n, 1); // show(1, n, 1); } else if(op[0]=='D') { putchar(10); break; } } } return 0; }