给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白
有两种操作:
0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)
1 v : 询问1到v的路径上的第一个黑点,若无,输出-1
方法1:树剖线段树上维护深度最小的黑点。
方法2:统计点到根的路径有几个黑点,倍增向上跳。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
const int INF=1e9+7;
typedef pair<int,int>par;
#define mp make_pair
struct edge{
int to,next;
}e[MAXN<<1];
int head[MAXN],cnt=0;
inline void add(int u,int v){e[++cnt]=(edge){v,head[u]},head[u]=cnt;}
int n,m;
int fa[MAXN],hson[MAXN],size[MAXN],dep[MAXN];
void dfs1(int u,int father){
size[u]=1;
dep[u]=dep[father]+1;
fa[u]=father;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==father)continue;
dfs1(v,u);
size[u]+=size[v];
if(!hson[u]||size[hson[u]]<size[v])hson[u]=v;
}
}
int id[MAXN],rl[MAXN],top[MAXN],num=0;
void dfs2(int u,int tp){
top[u]=tp;
id[u]=++num;
rl[num]=u;
if(hson[u])dfs2(hson[u],tp);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int deeeeep[MAXN<<2],blk[MAXN<<2];
struct xds{
#define lson (o<<1)
#define rson (o<<1|1)
inline void pushup(int o){
if(deeeeep[lson]<deeeeep[rson]) deeeeep[o]=deeeeep[lson],blk[o]=blk[lson];
else deeeeep[o]=deeeeep[rson],blk[o]=blk[rson];
}
void build(int o,int l,int r){
if(l==r){deeeeep[o]=INF;blk[o]=-1;return;}
int mid=l+r>>1;
build(lson,l,mid);build(rson,mid+1,r);
pushup(o);
}
par query(int o,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r){return mp(deeeeep[o],blk[o]);}
int mid=l+r>>1;
par t1=mp(INF,-1),t2=mp(INF,-1);
if(ql<=mid){
t1=query(lson,l,mid,ql,qr);
}
if(qr>mid){
t2=query(rson,mid+1,r,ql,qr);
if(t2.first<t1.first)t1.first=t2.first,t1.second=t2.second;
}
return mp(t1.first,t1.second);
}
void change(int o,int l,int r,int pos){
if(l==r){
if(deeeeep[o]!=INF)deeeeep[o]=INF,blk[o]=-1;
else deeeeep[o]=dep[rl[l]],blk[o]=rl[l];
return;
}
int mid=l+r>>1;
if(pos<=mid)change(lson,l,mid,pos);
else change(rson,mid+1,r,pos);
pushup(o);
}
}T;
int chain_query(int x,int y){
int tx=top[x],ty=top[y];
par t1=mp(INF,-1),t2=mp(INF,-1);
while(tx!=ty){
if(dep[tx]<dep[ty]){
t2=T.query(1,1,n,id[ty],id[y]);
if(t2.first<t1.first)t1.first=t2.first,t1.second=t2.second;
y=fa[ty];
}
else{
t2=T.query(1,1,n,id[tx],id[x]);
if(t2.first<t1.first)t1.first=t2.first,t1.second=t2.second;
x=fa[tx];
}
tx=top[x],ty=top[y];
}
if(dep[x]<dep[y])swap(x,y);
t2=T.query(1,1,n,id[y],id[x]);
if(t2.first<t1.first)t1.first=t2.first,t1.second=t2.second;
return t1.second;
}
int main(){
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs1(1,1);
dfs2(1,1);
T.build(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
if(u)printf("%d\n",chain_query(u,v));
else T.change(1,1,n,id[v]);
}
return 0;
}