树上莫队TLE on #1求调教(悬一关)
查看原帖
树上莫队TLE on #1求调教(悬一关)
754502
_AyachiNene楼主2023/11/23 17:16
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int res=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
	return res*f;
}
void write(int x)
{
	if(x<0){putchar('-');x=-x;}
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
struct node
{
	int nxt,to;
}e[114514];
int head[114514],cnt_edge;
void add(int u,int v)
{
	e[++cnt_edge].to=v;
	e[cnt_edge].nxt=head[u];
	head[u]=cnt_edge;
}
struct que
{
	int l,r,Lca,id;
}q[114514];
//--------TreeCutLcaBegin----------
int f[114514],dep[114514],son[114514],top[114514],siz[114514];
void dfs1(int u,int fa)
{
	f[u]=fa;
	siz[u]=1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa)
			continue;
		dep[v]=dep[u]+1;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void dfs2(int u,int t)
{
	top[u]=t;
	if(son[u])
		dfs2(son[u],t);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==f[u]||v==son[u])
			continue;
		dfs2(v,v);
	}
}
int lca(int x,int y)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		x=f[top[x]];
	}
	return dep[x]<dep[y]?x:y;
}
//-----------TreeCutLcaEnd---------
int n,m;
int a[114514],b[114514];
int euldfn[114514],cnt_dfn;
int posf[114514],posl[114514];
void dfs_eul(int u,int fa)
{
	euldfn[++cnt_dfn]=u;
	posf[u]=cnt_dfn;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa)
			continue;
		dfs_eul(v,u);
	}
	euldfn[++cnt_dfn]=u;
	posl[u]=cnt_dfn;
}
int belong[114514],size;
int ans[114514],t[114514],cnt[114514],l=1,r,now;
bool cmp(que x,que y)
{
	if(belong[x.l]==belong[y.l])
		return x.r<y.r;
	return belong[x.l]<belong[y.l];
}
inline void add(int x)
{
	if(!cnt[a[euldfn[x]]])
		++now;
	++cnt[a[euldfn[x]]];
}
inline void del(int x)
{
	--cnt[a[euldfn[x]]];
	if(!cnt[a[euldfn[x]]])
		--now;
}
inline void update(int x)
{
	if(t[euldfn[x]])
		del(x);
	else
		add(x);
	t[euldfn[x]]^=1;
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		b[i]=a[i]=read();
	sort(b+1,b+n+1);
	int tot=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		add(u,v);
		add(v,u);
	}
	dfs_eul(1,0);
	dfs1(1,0);
	dfs2(1,1);
	size=sqrt(n);
	for(int i=1;i<=n;i++)
		belong[i]=i/size+1;
	for(int i=1;i<=m;i++)
	{
		int x=read(),y=read();
		if(posf[x]>posf[y])
			swap(x,y);
		q[i].Lca=lca(x,y);
		q[i].id=i;
		if(q[i].Lca==x)
		{
			q[i].l=posf[x],q[i].r=posf[y];
			q[i].Lca=0;
		}
		else
			q[i].l=posl[x],q[i].r=posf[y];
	}
	sort(q+1,q+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		while(l<q[i].l)
			update(l++);
		while(l>q[i].l)
			update(--l);
		while(r<q[i].r)
			update(++r);
		while(r>q[i].r)
			update(r--);
		if(q[i].Lca)
			update(q[i].Lca);
		ans[q[i].id]=now;
		if(q[i].Lca)
			update(q[i].Lca);
	}
	for(int i=1;i<=m;i++)
		write(ans[i]),puts("");
}
2023/11/23 17:16
加载中...