首页 > 代码库 > SPOJ QTREE3 - Query on a tree again!

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 81 21 32 42 95 97 98 96 81 30 81 61 70 21 90 21 9 Output:-18-12-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)

在线段树上维护区间内深度最浅的黑色点位置即可,注意线段树结点到原树的反向映射

 

  1 #include<iostream>  2 #include<cstdio>  3 #include<algorithm>  4 #include<cstring>  5 #include<queue>  6 using namespace std;  7 const int INF=1e9;  8 const int mxn=100010;  9 int read(){ 10     int x=0,f=1;char ch=getchar(); 11     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} 12     while(ch>=0 && ch<=9){x=x*10-0+ch;ch=getchar();} 13     return x*f; 14 } 15 struct edge{int v,nxt;}e[mxn<<1]; 16 int hd[mxn],mct=0; 17 int n,q; 18 void add_edge(int u,int v){ 19     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return; 20 } 21 struct node{ 22     int fa,son; 23     int top,size; 24     int w; 25 }t[mxn]; 26 int sz=0; 27 int dep[mxn]; 28 int id[mxn]; 29 void DFS1(int u,int fa){ 30     dep[u]=dep[fa]+1; 31     t[u].size=1; 32     for(int i=hd[u];i;i=e[i].nxt){ 33         int v=e[i].v;if(v==fa)continue; 34         t[v].fa=u; 35         DFS1(v,u); 36         t[u].size+=t[v].size; 37         if(t[v].size>t[t[u].son].size)  38             t[u].son=v; 39     } 40     return; 41 } 42 void DFS2(int u,int top){ 43     t[u].w=++sz;t[u].top=top; 44     id[sz]=u; 45     if(t[u].son)DFS2(t[u].son,top); 46     for(int i=hd[u];i;i=e[i].nxt){ 47         int v=e[i].v; 48         if(v==t[u].fa || v==t[u].son)continue; 49         DFS2(v,v); 50     } 51     return; 52 } 53 struct SGT{ 54     int ps; 55     int c; 56 }st[mxn<<2]; 57 void Build(int l,int r,int rt){ 58     st[rt].ps=INF; 59     if(l==r)return; 60     int mid=(l+r)>>1; 61     Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1); 62     return; 63 } 64 void update(int p,int l,int r,int rt){ 65     if(l==r){ 66         st[rt].c^=1; 67         st[rt].ps=(st[rt].c)?l:INF; 68         return; 69     } 70     int mid=(l+r)>>1; 71     if(p<=mid)update(p,l,mid,rt<<1); 72     else update(p,mid+1,r,rt<<1|1); 73     st[rt].ps=min(st[rt<<1].ps,st[rt<<1|1].ps); 74     return; 75 } 76 int query(int L,int R,int l,int r,int rt){ 77     if(L<=l && r<=R){return st[rt].ps;} 78     int mid=(l+r)>>1; 79     int res=INF; 80     if(L<=mid)res=min(res,query(L,R,l,mid,rt<<1)); 81     if(R>mid && res>mid)res=min(res,query(L,R,mid+1,r,rt<<1|1)); 82     return res; 83 } 84 int Qt(int x,int y){ 85     int res=INF; 86     while(t[x].top!=t[y].top){ 87         if(dep[t[x].top]<dep[t[y].top])swap(x,y); 88         res=min(res,query(t[t[x].top].w,t[x].w,1,n,1)); 89         x=t[t[x].top].fa; 90     } 91     if(dep[x]>dep[y])swap(x,y); 92     res=min(res,query(t[x].w,t[y].w,1,n,1)); 93     return res; 94 } 95 int main(){ 96     int i,j,u,v; 97     n=read();q=read(); 98     for(i=1;i<n;i++){ 99         u=read();v=read();100         add_edge(u,v);101         add_edge(v,u);102     }103     DFS1(1,0);104     DFS2(1,1);105     Build(1,n,1);106     while(q--){107         u=read();v=read();108         if(!u)109             update(t[v].w,1,n,1);110         else{111             int ans=Qt(1,v);112             if(ans>=INF){printf("-1\n");continue;}113             ans=id[ans];114             printf("%d\n",ans);115         }116     }117     return 0;118 }

 

SPOJ QTREE3 - Query on a tree again!