题解 P4116 【Qtree3】
题目
P4116 Qtree3
思路
树链剖分。
Code
#include<cstdio>
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#define MAXN 100001
#define inf 2147483647
inline void read(int &T) {
int x=0;bool f=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
T=f?-x:x;
}
int n,q,dfn[MAXN],pre[MAXN],size[MAXN];
int min(int a,int b) {return a<b?a:b;}
namespace Seg {
#define lson now<<1
#define rson now<<1|1
struct Node {
int l,r,w;
}tree[MAXN<<2];
void build(int l,int r,int now) {
tree[now].l=l,tree[now].r=r;
if(tree[now].l==tree[now].r) {
tree[now].w=inf;return;
}
int mid=(tree[now].l+tree[now].r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
tree[now].w=min(tree[lson].w,tree[rson].w);
}
void update(int x,int now) {
if(tree[now].l==tree[now].r) {
if(tree[now].w!=inf) tree[now].w=inf;
else tree[now].w=tree[now].l;
return;
}
int mid=(tree[now].l+tree[now].r)>>1;
if(x<=mid) update(x,lson);
else update(x,rson);
tree[now].w=min(tree[lson].w,tree[rson].w);
}
int query(int x,int y,int now) {
if(tree[now].l>=x&&tree[now].r<=y) return tree[now].w;
int mid=(tree[now].l+tree[now].r)>>1,ans=inf;
if(x<=mid) ans=min(ans,query(x,y,lson));
if(y>mid) ans=min(ans,query(x,y,rson));
return ans;
}
}
namespace Cut {
int cnt,pthn,head[MAXN],dep[MAXN];
int fa[MAXN],son[MAXN],top[MAXN];
struct Edge {
int next,to;
}pth[MAXN<<1];
void add(int from,int to) {
pth[++pthn].to=to,pth[pthn].next=head[from];
head[from]=pthn;
}
void dfs1(int u,int father) {
fa[u]=father,dep[u]=dep[father]+1,size[u]=1;
for(int i=head[u];i;i=pth[i].next) {
int x=pth[i].to;
if(x!=father) {
dfs1(x,u),size[u]+=size[x];
if(size[son[u]]<size[x]) son[u]=x;
}
}
}
void dfs2(int u,int tp) {
top[u]=tp,dfn[u]=++cnt,pre[cnt]=u;
if(son[u]) dfs2(son[u],tp);
for(int i=head[u];i;i=pth[i].next) {
int x=pth[i].to;
if(x!=fa[u]&&x!=son[u]) dfs2(x,x);
}
}
int ask(int x,int y) {
int ans=inf;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
ans=min(ans,Seg::query(dfn[top[x]],dfn[x],1));
x=fa[top[x]];
}
if(dep[x]>dep[y]) std::swap(x,y);
ans=min(ans,Seg::query(dfn[x],dfn[y],1));
if(ans==inf) return -1;
return ans;
}
}
int main() {
read(n),read(q);
for(int i=1,u,v;i<n;++i) {
read(u),read(v);
Cut::add(u,v),Cut::add(v,u);
}
Cut::dfs1(1,1),Cut::dfs2(1,1),Seg::build(1,n,1);
for(int i=1,opt,x;i<=q;++i) {
read(opt),read(x);
if(opt==0) Seg::update(dfn[x],1);
else {
int ccc=Cut::ask(1,x);
if(ccc==-1) puts("-1");
else printf("%d\n",pre[ccc]);
}
}
return 0;
}