SPOJ QTREE3 - Query on a tree again!
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:
- 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.
Example
Input: 9 8 1 2 1 3 2 4 2 9 5 9 7 9 8 9 6 8 1 3 0 8 1 6 1 7 0 2 1 9 0 2 1 9 Output: -1 8 -1 2 -1
Constraints & Limits
There are 12 real input files.
For 1/3 of the test cases, N=5000, Q=400000.
For 1/3 of the test cases, N=10000, Q=300000.
For 1/3 of the test cases, N=100000, Q=100000.
一棵树,点数<=100000,初始全是白点,支持两种操作:
1.将某个点的颜色反色。
2.询问某个点至根节点路径上第一个黑点是哪个。
树链剖分
注意到询问的链都是(1,v)
在线段树上维护区间内深度最浅的黑色点位置即可,注意线段树结点到原树的反向映射
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=1e9; const int mxn=100010; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();} return x*f; } struct edge{int v,nxt;}e[mxn<<1]; int hd[mxn],mct=0; int n,q; void add_edge(int u,int v){ e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return; } struct node{ int fa,son; int top,size; int w; }t[mxn]; int sz=0; int dep[mxn]; int id[mxn]; void DFS1(int u,int fa){ dep[u]=dep[fa]+1; t[u].size=1; for(int i=hd[u];i;i=e[i].nxt){ int v=e[i].v;if(v==fa)continue; t[v].fa=u; DFS1(v,u); t[u].size+=t[v].size; if(t[v].size>t[t[u].son].size) t[u].son=v; } return; } void DFS2(int u,int top){ t[u].w=++sz;t[u].top=top; id[sz]=u; if(t[u].son)DFS2(t[u].son,top); for(int i=hd[u];i;i=e[i].nxt){ int v=e[i].v; if(v==t[u].fa || v==t[u].son)continue; DFS2(v,v); } return; } struct SGT{ int ps; int c; }st[mxn<<2]; void Build(int l,int r,int rt){ st[rt].ps=INF; if(l==r)return; int mid=(l+r)>>1; Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1); return; } void update(int p,int l,int r,int rt){ if(l==r){ st[rt].c^=1; st[rt].ps=(st[rt].c)?l:INF; return; } int mid=(l+r)>>1; if(p<=mid)update(p,l,mid,rt<<1); else update(p,mid+1,r,rt<<1|1); st[rt].ps=min(st[rt<<1].ps,st[rt<<1|1].ps); return; } int query(int L,int R,int l,int r,int rt){ if(L<=l && r<=R){return st[rt].ps;} int mid=(l+r)>>1; int res=INF; if(L<=mid)res=min(res,query(L,R,l,mid,rt<<1)); if(R>mid && res>mid)res=min(res,query(L,R,mid+1,r,rt<<1|1)); return res; } int Qt(int x,int y){ int res=INF; while(t[x].top!=t[y].top){ if(dep[t[x].top]<dep[t[y].top])swap(x,y); res=min(res,query(t[t[x].top].w,t[x].w,1,n,1)); x=t[t[x].top].fa; } if(dep[x]>dep[y])swap(x,y); res=min(res,query(t[x].w,t[y].w,1,n,1)); return res; } int main(){ int i,j,u,v; n=read();q=read(); for(i=1;i<n;i++){ u=read();v=read(); add_edge(u,v); add_edge(v,u); } DFS1(1,0); DFS2(1,1); Build(1,n,1); while(q--){ u=read();v=read(); if(!u) update(t[v].w,1,n,1); else{ int ans=Qt(1,v); if(ans>=INF){printf("-1\n");continue;} ans=id[ans]; printf("%d\n",ans); } } return 0; }
- spoj2798 QTREE3 Query on a tree again!
- SPOJ QTREE3 Query on a tree again! 树链剖分
- spoj 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!
- SPOJ375——Query on a tree(树链剖分模板详解以及入门)
- spoj 375 Query on a tree
- SPOJ Query on a tree 树链剖分 水题
- SPOJ375 Query on a tree
- SPOJ375 Query on a tree(树链剖分)
- bzoj 1803: Spoj1487 Query on a tree III(主席树)
- SPOJ QTREE4 Query on a tree IV (边分治 + 堆)
- SPOJ Query on a tree IV【LCT】
- spoj 375 QTREE - Query on a tree 树链剖分边权模板
- SPOJ Query on a tree(dfs序+树链剖分)
- SPOJ-375 QTREE - Query on a tree (树链剖分 边权转点权)
- 树链剖分+线段树 spoj375 Query on a tree