点分树,不知为啥 TLE
查看原帖
点分树,不知为啥 TLE
367521
roger_yrj楼主2025/2/6 12:37
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define mp make_pair
#define A first
#define B second
using namespace std;
const int N=1e5+10;
int n,col[N];
int st[N<<1][30],tot,pos[N],dep[N];
int fst[N],nxt[N<<1],to[N<<1],ecnt;
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x;
}
inline void adde(int u,int v){
	ecnt++;
	to[ecnt]=v;
	nxt[ecnt]=fst[u];
	fst[u]=ecnt;
}
inline void dfs0(int u,int fa){
	dep[u]=dep[fa]+1;
	st[++tot][0]=dep[u];
	pos[u]=tot;
	for(int i=fst[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa)continue;
		dfs0(v,u);
		st[++tot][0]=dep[u];
	}
}
inline int query_dis(int u,int v){
	int l=pos[u],r=pos[v];
	if(l>r)swap(l,r);
	int k=__lg(r-l+1);
	return dep[u]+dep[v]-2*min(st[l][k],st[r-(1<<k)+1][k]);
}
int rt,siz[N],maxx[N],f[N],Siz,vis[N];
multiset<pii>c[N];
inline void getrt(int u,int fa){
	siz[u]=1;
	for(int i=fst[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa||vis[v])continue;
		getrt(v,u);
		siz[u]+=siz[v];
		maxx[u]=max(maxx[u],siz[v]);
	}
	maxx[u]=max(maxx[u],Siz-siz[u]);
	if(!rt||maxx[u]<maxx[rt])rt=u;
}
inline void getsiz(int u,int fa){
	siz[u]=1;
	for(int i=fst[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa||vis[v])continue;
		getsiz(v,u);
		siz[u]+=siz[v];
	}
}
inline void dfs(int u,int fa){//Only Build
	f[u]=fa;
	vis[u]=1;
	getsiz(u,0);
//	siz[u]=Siz;
	for(int i=fst[u];i;i=nxt[i]){
		int v=to[i];
		if(vis[v])continue;
		Siz=siz[v];rt=0;
		getrt(v,u);
		dfs(rt,u);
	}
}
inline void updata(int u){
	col[u]^=1;
	if(col[u]){
		for(int i=u;i;i=f[i])c[i].insert(mp(query_dis(u,i),u));
	}else{
		for(int i=u;i;i=f[i])c[i].erase(mp(query_dis(u,i),u));
	}
}
inline int Query(int u){
	int ret=1145141919;
	for(int i=u;i;i=f[i])if(!c[i].empty())
	ret=min(ret,query_dis(u,i)+(*c[i].begin()).A);
	if(ret==1145141919)return -1;
	return ret;
}
int main(){
	cin>>n;
	for(int i=1,u,v;i<n;i++){
		u=read(),v=read();
		adde(u,v);
		adde(v,u);
	}
	dfs0(1,0);
	for(int j=1;j<=20;j++){
		for(int i=1;i+(1<<j)-1<=tot;i++){
			st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
	Siz=n;
	getrt(1,0);
	dfs(rt,0);
	int T;cin>>T;
	while(T--){
		int op=read(),u=read();
		if(op==0)updata(u);
		else printf("%d\n",Query(u));
	} 
}
2025/2/6 12:37
加载中...