为什么TLE
查看原帖
为什么TLE
965755
u______n楼主2023/12/20 18:53
#pragma GCC optimize("Ofast", "inline", "-ffast-math") 
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100015;
int n,Q;
vector<int> G[N];
bool y[N];
void add(int u,int v)
{
	G[u].push_back(v);
	G[v].push_back(u);
}
int dp[N][2],dep[N];
int dn,dfn[N];
int st[20][N];
int get(int x,int y)
{
	return dfn[x]<dfn[y]? x:y;
}
void dfs0(int u,int fa)
{
	st[0][dfn[u]=++dn]=fa;
	dep[u]=dep[fa]+1;
	for(int v:G[u])
	{
		if(v!=fa)
		dfs0(v,u);
	}
}
void init()
{
	dfs0(1,0);
	for(int i=1;i<=__lg(n);i++)
	for(int j=1;j+(1<<i)-1<=n;j++)
	st[i][j]=get(st[i-1][j],st[i-1][j+(1<<(i-1))]);
}
int lca(int u,int v)
{
	if(u==v)
	return u;
	if((u=dfn[u])>(v=dfn[v]))
	swap(u,v);
	int d=__lg(v-u++);
	return get(st[d][u],st[d][v-(1<<d)+1]);
}
int dis(int u,int v)
{
//	cout<<u<<" "<<v<<" "<<lca(u,v)<<" "<<dep[u]<<" "<<dep[v]<<" "<<dep[lca(u,v)]<<endl;
	return dep[u]+dep[v]-2*dep[lca(u,v)];
}
void dfs1(int u,int fa)
{
	if(y[u])
	dp[u][0]=0;
	for(int v:G[u])
	{
		if(v==fa)
		continue;
		dfs1(v,u);
		dp[u][0]=min(dp[u][0],dp[v][0]+1);
	}
}
struct node
{
	int num;
	int val;
};
struct cmp
{
	bool operator()(const node &a,const node &b)const
	{
		if(a.val!=b.val)
		return a.val>b.val;
		else
		return a.num>b.num;
	}
};
bool shan[N];
priority_queue<node,vector<node>,cmp> q;
void dfs2(int u,int fa)
{
	dp[u][1]=min(dp[u][1],dp[u][0]);
	q.push({u,-dep[u]+dp[u][0]});
	for(int v:G[u])
	{
		if(v==fa)
		continue;
		dfs2(v,u);
	}
	while(!q.empty()&&shan[q.top().num])
	q.pop();
	if(!q.empty())
	{
		int num=q.top().num;
		dp[u][1]=min(dp[u][1],dp[num][0]+dis(num,u));
	}
	shan[u]=1;
//	cout<<"*"<<u<<" "<<q.size()<<" "<<dp[u][0]<<" "<<dp[u][1]<<endl;
}
vector<int> now;
void cg()
{
	while(!q.empty())
	q.pop();
	for(int i=1;i<=n;i++)
	{
	dp[i][0]=1e9;
	dp[i][1]=1e9;
	shan[i]=0;
	}
	dfs1(1,0);
//	cout<<"<"<<endl;
	dfs2(1,0);
//	cout<<"<<"<<endl;
	now.clear();
}
void work()
{
	int B=sqrt(Q)+1;
	int tot=0,i=1;
	y[1]=1;
	init();
	cg();
	for(;tot<Q;)
	{
		//cout<<tot<<"__________________"<<endl;
		tot+=B;
		tot=min(tot,Q);
		for(;i<=tot;i++)
		{
		//	cout<<"*"<<i<<endl;
			int op,p;
			cin>>op>>p;
			if(op==1)
			{
				y[p]=1;
				now.push_back(p);
			}
			else
			{
				int ans=dp[p][1];
				for(int k:now)
				ans=min(ans,dis(p,k));
				cout<<ans<<endl;
			}
		}
		cg();
	}
}
signed main(){
	cin>>n>>Q;
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	work();
	return 0;
}

使用操作分块方法,理论上应该是n^1.5 log(n)的

2023/12/20 18:53
加载中...