spoj QTREE3 Query on a tree again!
2017-02-13 18:21
351 查看
You are given a tree (an acyclic undirected connected graph) with N
nodes. The tree nodes are numbered from 1 to N. In the start, the
color of any node in the tree is white.
We will ask you to perfrom some instructions of the following form:
Input
In the first line there are two integers N and Q.
In the next N-1 lines describe the edges in the tree: a line with two
integers a b denotes an edge between a and b.
The next Q lines contain instructions “0 i” or “1 v” (1 ≤ i, v ≤ N).
Output
For each “1 v” operation, write one integer representing its result.
树链剖分,维护路径上深度最小的黑点。
nodes. The tree nodes are numbered from 1 to N. In the start, the
color of any node in the tree is white.
We will ask you to perfrom some instructions of the following form:
0 i : change the color of the i-th node (from white to black, or from black to white); or 1 v : ask for the id of the first black node on the path from node 1 to node v. if it doesn't exist, you may return -1 as its result.
Input
In the first line there are two integers N and Q.
In the next N-1 lines describe the edges in the tree: a line with two
integers a b denotes an edge between a and b.
The next Q lines contain instructions “0 i” or “1 v” (1 ≤ i, v ≤ N).
Output
For each “1 v” operation, write one integer representing its result.
树链剖分,维护路径上深度最小的黑点。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int fir[100010],ne[200010],to[200010], val[1000010], dep[100010],fa[100010],size[100010], son[100010],pos[100010],top[100010], n,q,clo; void add(int num,int u,int v) { ne[num]=fir[u]; fir[u]=num; to[num]=v; } void dfs1(int u) { int v; size[u]=1; for (int i=fir[u];i;i=ne[i]) if ((v=to[i])!=fa[u]) { dep[v]=dep[u]+1; fa[v]=u; dfs1(v); size[u]+=size[v]; if (!son[u]||size[son[u]]<size[v]) son[u]=v; } } void dfs2(int u) { int v; pos[u]=++clo; if (son[u]) { top[son[u]]=top[u]; dfs2(son[u]); } for (int i=fir[u];i;i=ne[i]) if ((v=to[i])!=fa[u]&&v!=son[u]) { top[v]=v; dfs2(v); } } void build(int p,int L,int R) { val[p]=-1; if (L==R) return; int mid=L+R>>1; if (L<=mid) build(p*2,L,mid); if (mid<R) build(p*2+1,mid+1,R); } void init() { int u,v; scanf("%d%d",&n,&q); for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(i*2,u,v); add(i*2+1,v,u); } dep[1]=1; dfs1(1); top[1]=1; dfs2(1); build(1,1,n); } void modi(int p,int L,int R,int u) { int x,y; if (L==R) { if (val[p]==-1) val[p]=u; else val[p]=-1; return; } int mid=L+R>>1; if (pos[u]<=mid) modi(p*2,L,mid,u); else modi(p*2+1,mid+1,R,u); x=L<=mid?val[p*2]:-1; y=mid<R?val[p*2+1]:-1; if (x==-1||(y>0&&dep[y]<dep[x])) val[p]=y; else val[p]=x; } int qry(int p,int L,int R,int l,int r) { int x,y; if (l<=L&&R<=r) return val[p]; int mid=L+R>>1; x=l<=mid?qry(p*2,L,mid,l,r):-1; y=r>mid?qry(p*2+1,mid+1,R,l,r):-1; if (x==-1||(y>0&&dep[y]<dep[x])) return y; return x; } int query(int u) { int ans=-1,x; while (top[u]!=1) { x=qry(1,1,n,pos[top[u]],pos[u]); if (x>0&&(ans==-1||dep[x]<dep[ans])) ans=x; u=fa[top[u]]; } x=qry(1,1,n,1,pos[u]); if (x>0&&(ans==-1||dep[x]<dep[ans])) ans=x; return ans; } int main() { int u,x; init(); while (q--) { scanf("%d%d",&x,&u); if (x) printf("%d\n",query(u)); else modi(1,1,n,u); } }
相关文章推荐
- SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree
- 动态树LCT||树链剖分+线段树(SPOJ QTREE3 - Query on a tree again!)
- spoj Query on a tree again(树链剖分)
- SPOJ QTREE3 - Query on a tree again!
- 【SPOJ】2798 Query on a tree again!
- SPOJ 2798 Query on a tree again 树链剖分
- 【SPOJ】2798 Query on a tree again! QTREE系列之3 树链剖分
- spoj 2798 Query on a tree again! 树链剖分
- SPOJ 2798 Query on a tree again!
- spoj2798 QTREE3 Query on a tree again!
- SPOJ QTREE3 Query on a tree again! 树链剖分
- spoj375QTREE - Query on a tree【树链刨分】
- SPOJ Query on a tree II (倍增LCA)
- 【SPOJ QTREE2】QTREE2 - Query on a tree II(LCA)
- SPOJ375 Query on a tree(LCT边权)
- SPOJ QTREE Query on a tree
- 【SPOJ】913 Query on a tree II
- HDU 4836 The Query on the Tree (欧拉序列,线段树,动态树)
- HDU 6191 Query on A Tree(字典树)
- [BZOJ 3637]Query on a tree VI