萌新求助树上莫队
查看原帖
萌新求助树上莫队
358739
BFSDFS123楼主2022/1/26 13:30

rt

第一个数据点就 TLE 了。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
//#define LL_inf 1145141919810
#define ull unsigned long long
#define ll long long
using namespace std;
const int Maxn=2e5+10;
const int Maxm=2e5+10;
int head[Maxn],tot;
struct Edge{
	int to;
	int nxt;
}E[Maxn<<1];
int n,m;
void addedge(int u,int v)
{
	tot++;
	E[tot].to=v;
	E[tot].nxt=head[u];
	head[u]=tot;
}
int L[Maxn],R[Maxn],cnt;
int pot[Maxn<<2];
namespace LCA
{
	int dep[Maxn],fa[Maxn],tp[Maxn],siz[Maxn],son[Maxn];
	void dfs1(int u,int f)
	{
		dep[u]=dep[f]+1;
		fa[u]=f;
		siz[u]=1;
		L[u]=++cnt;
		pot[cnt]=u;
		int tmp=-1;
		for(int i=head[u];i;i=E[i].nxt)
		{
			int v=E[i].to;
			if(v!=f)
			{
				dfs1(v,u);
				siz[u]+=siz[v];
				if(tmp<siz[v])
				{
					tmp=siz[v];
					son[u]=v;
				}
			}
		}
		
		R[u]=++cnt;
		pot[cnt]=u;
	}
	void dfs2(int u,int Top)
	{
		tp[u]=Top;
		if(!son[u])
		{
			return ;
		}
		dfs2(son[u],Top);
		for(int i=head[u];i;i=E[i].nxt)
		{
			int v=E[i].to;
			if(v==fa[u] || v==son[u])
			{
				continue;
			}
			dfs2(v,v);
		}
	}
	int lca(int x,int y)
	{
		while(tp[x]!=tp[y])
		{
			if(dep[tp[x]]<dep[tp[y]])
			{
				swap(x,y);
			}
			x=fa[tp[x]];
		}
		if(dep[x]>dep[y]) swap(x,y);
		return x;
	}
}
int block,belong[Maxn];
int Ar[Maxn];
struct Query{
	int l,r;
	int id;
	int lca;
	bool operator<(const Query &rhs)const{
		return belong[l]==belong[rhs.l]?r<rhs.r:belong[l]<belong[rhs.l];
    }
}q[Maxm];
int res=0;
int mp[Maxn];
void add(int x)
{
	mp[x]++;
	if(mp[x]==1)
	{
		res++;
	}
}
void del(int x)
{
	mp[x]--;
	if(mp[x]==0)
	{
		res--;
	}
}
int used[Maxm];
void Add(int x)
{
	used[x]?del(Ar[x]):add(Ar[x]);
	used[x]^=1; 
}
int Br[Maxn];
int out[Maxm];
int main()
{
	scanf("%d%d",&n,&m);
	block=sqrt(n*2);
	for(int i=1;i<=n;i++)
	{
		belong[i]=(i-1)/block+1;
		scanf("%d",&Ar[i]);
		Br[i]=Ar[i];
	}
	sort(Br+1,Br+1+n);
	int newn=unique(Br+1,Br+1+n)-Br-1;
	for(int i=1;i<=n;i++)
	{
		Ar[i]=lower_bound(Br+1,Br+1+n,Ar[i])-Br;
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
		addedge(v,u);
	}
	LCA::dfs1(1,0);
	LCA::dfs2(1,1);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		if(L[u]>L[v])
		{
			swap(u,v);
		}
		int Lca=LCA::lca(u,v);
//		cout<<"Lca="<<Lca<<endl;
		q[i].id=i;
		if(Lca==u)
		{
			q[i].l=L[u];
			q[i].r=L[v];
		}else{
			q[i].l=R[u];
			q[i].r=L[v];
			q[i].lca=Lca;
		}
	}
	sort(q+1,q+1+m);
//	for(int i=1;i<=n;i++)
//	{
//		printf("i:L/R:%d %d\n",L[i],R[i]);
//	}
	int l=1,r=0;
	for(int i=1;i<=m;i++)
	{
		while(l<q[i].l) Add(pot[l++]);//,printf("l=%d,r=%d,res=%d\n",l,r,res);
		while(l>q[i].l) Add(pot[--l]);//,printf("l=%d,r=%d,res=%d\n",l,r,res);
		while(r<q[i].r) Add(pot[++r]);//,printf("l=%d,r=%d,res=%d\n",l,r,res);
		while(r>q[i].r) Add(pot[r--]);//,printf("l=%d,r=%d,res=%d\n",l,r,res);
		if(q[i].lca)
		{
			Add(q[i].lca);
		}
		out[q[i].id]=res;
		if(q[i].lca)
		{
			Add(q[i].lca);
		}
	}
	for(int i=1;i<=m;i++)
	{
		printf("%d\n",out[i]);
	}
	return 0;
}
2022/1/26 13:30
加载中...