P4116 倍增树剖求条
  • 板块灌水区
  • 楼主lfxxx_
  • 当前回复14
  • 已保存回复14
  • 发布时间2024/10/8 19:49
  • 上次更新2024/10/8 21:30:15
查看原帖
P4116 倍增树剖求条
795344
lfxxx_楼主2024/10/8 19:49
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m;
int tr[N<<2];
void pushup(int p){tr[p]=tr[p<<1]+tr[p<<1|1];}
void update(int p,int pl,int pr,int x)
{
	if(x<pl||pr<x)
		return ;
	if(pl==x&&pr==x)
	{
		tr[p]^=1;
		return ;
	}
	int mid=(pl+pr)>>1;
	update(p<<1,pl,mid,x);
	update(p<<1|1,mid+1,pr,x);
	pushup(p);
}
int query(int p,int pl,int pr,int L,int R)
{
	if(R<pl||pr<L)
		return 0;
	if(L<=pl&&pr<=R)
		return tr[p];
	int mid=(pl+pr)>>1;
	return query(p<<1,pl,mid,L,R)+query(p<<1|1,mid+1,pr,L,R);
}
vector<int>edge[N];
int dp[N][21],dep[N],sz[N],son[N];
int dfn[N],rnk[N],top[N],id;
void dfs1(int u,int ft)
{
	dp[u][0]=ft;
	dep[u]=dep[ft]+1;
	sz[u]=1;
	son[u]=-1;
	for(int i=1;i<=20;++i)
		dp[u][i]=dp[dp[u][i-1]][i-1];
	for(auto &v:edge[u])
	{
		if(v==ft)
			continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[v]>sz[son[u]])
			son[u]=v;
	}
}
void dfs2(int u,int t)
{
	top[u]=t;
	dfn[u]=++id;
	rnk[id]=u;
	if(~son[u])
		dfs2(son[u],t);
	for(auto &v:edge[u])
	{
		if(v==son[u]||v==dp[u][0])
			continue;
		dfs2(v,v);
	}
}
int calc(int x,int k)
{
	int res=x;
	for(int i=20;i>=0;--i)
		if(k&(1<<i))
			res=dp[res][i];
	return res;
}
int qrange(int x,int y)
{
	int res=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res+=query(1,1,n,dfn[top[x]],dfn[x]);
		x=dp[top[x]][0];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	return res+query(1,1,n,dfn[x],dfn[y]);
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<n;++i)
	{
		int u,v;
		cin>>u>>v;
		edge[u].emplace_back(v);
		edge[v].emplace_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	while(m--)
	{
		int op,x;
		cin>>op>>x;
		if(!op)
			update(1,1,n,dfn[x]);
		else
		{
			if(qrange(x,x))
			{
				cout<<x<<'\n';
				continue;
			}
			int l=0,r=n+1;
			while(l+1<r)
			{
				int mid=(l+r)>>1;
				if(!calc(x,mid)||qrange(x,calc(x,mid)))
					r=mid;
				else
					l=mid;
			}
			if(!calc(x,r))
				cout<<"-1\n";
			else
				cout<<calc(x,r)<<'\n';
		}
	}
}
2024/10/8 19:49
加载中...