您的位置:首页 > 产品设计 > UI/UE

SPOJ QTREE3 - Query on a tree again!

2017-02-02 17:52 381 查看

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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: