SPOJ375 Query on a tree(树链剖分)
题意
给出一棵树,每条边都有权值,有两种操作:
- 把第p条边的权值改为x
- 询问x,y路径上的权值最大的边
code
#include<cstdio> #include<algorithm> #include<cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int N = 100010; struct Edge { int to,nxt,w; }e[200100]; int head ,tot,tn,n; int deth ,son ,fa ,siz ,bel ,pos ; int mx[N<<2],a ,b ,c ,data ; void init() { tot = tn = 0; memset(head,0,sizeof(head)); memset(son,0,sizeof(son)); } inline void add_edge(int u,int v,int w) { e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot; } void dfs1(int u,int pa) { siz[u] = 1; for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (v==pa) continue; fa[v] = u; deth[v] = deth[u] + 1; dfs1(v,u); siz[u] += siz[v]; if (son[u]==0 || siz[v] > siz[son[u]]) son[u] = v; } } void dfs2(int u,int top) { pos[u] = ++tn; bel[u] = top; if (!son[u]) return ; dfs2(son[u],top); for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (v != fa[u] && v != son[u]) dfs2(v,v); } } void pushup(int rt) { mx[rt] = max(mx[rt<<1],mx[rt<<1|1]); } void build(int l,int r,int rt) { if (l==r) { mx[rt] = data[l];return ; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } void update(int l,int r,int rt,int p,int x) { if (l==r) { mx[rt] = x;return ; } int m = (l + r) >> 1; if (p <= m) update(lson,p,x); else update(rson,p,x); pushup(rt); } int query(int l,int r,int rt,int L,int R) { if (L <= l && r <= R) { return mx[rt]; } int m = (l + r) >> 1; int ret = -1e9; if (L <= m) ret = max(ret,query(lson,L,R)); if (R > m) ret = max(ret,query(rson,L,R)); return ret; } void Change(int p,int x) { if (deth[a[p]] > deth[b[p]]) update(2,n,1,pos[a[p]],x); else update(2,n,1,pos[b[p]],x); } int Ask(int x,int y) { int ans = -1e9; while (bel[x] != bel[y]) { if (deth[bel[x]] < deth[bel[y]]) swap(x,y); ans = max(ans,query(2,n,1,pos[bel[x]],pos[x])); x = fa[bel[x]]; } if (deth[x] > deth[y]) swap(x,y); if (x != y) ans = max(ans,query(2,n,1,pos[x]+1,pos[y])); return ans; } int main() { char opt[15]; int T;scanf("%d",&T); while (T--) { init(); scanf("%d",&n); for (int i=1; i<n; ++i) { scanf("%d%d%d",&a[i],&b[i],&c[i]); add_edge(a[i],b[i],c[i]); add_edge(b[i],a[i],c[i]); } deth[1] = 1; dfs1(1,0); dfs2(1,1); for (int i=1; i<n; ++i) { if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos else data[pos[b[i]]] = c[i]; } build(2,n,1); scanf("%s",opt); while (opt[0]!='D') { int x,y; scanf("%d%d",&x,&y); if (opt[0]=='Q') printf("%d\n",Ask(x,y)); else Change(x,y); scanf("%s",opt); } } return 0; }
- 【SPOJ375】Query on a tree-树链剖分
- spoj 375--Query On a Tree [树链剖分]
- 【树链剖分模板】【SPOJ 375】 Query on a tree
- SPOJ 375 QTREE - Query on a tree 树链剖分+线段树(单点更新 区间查询最值)
- spoj375 Query on a tree(树链剖分)
- 树链剖分+线段树 spoj375 Query on a tree
- SPOJ 题目 375 QTREE - Query on a tree(树链剖分)
- spoj 375 Query on a tree 树链剖分
- spoj 375 QTREE - Query on a tree(树链剖分,边权)
- 【SPOJ375】 Query on a tree——树链剖分
- spoj 375 Query on a tree (树链剖分)
- SPOJ 375 Query on a tree(树链剖分)
- SPOJ 375 Query on a tree(树链剖分)
- [SPOJ 375]Query On a Tree(树链剖分)
- kyeremal-spoj375-Query on a tree-树链剖分
- SPOJ375——Query on a tree(树链剖分模板详解以及入门)
- SPOJ 375 QTREE Query on a tree 树链剖分水题
- spoj 375 Query on the tree [树链剖分]
- SPOJ 375 QTREE系列-Query on a tree (树链剖分)
- SPOJ 375 Query on a tree[树链剖分入门]