蒟蒻求教,树上莫队超时了
查看原帖
蒟蒻求教,树上莫队超时了
183609
hhoppitreeMadeline楼主2020/8/28 20:48
#include<bits/stdc++.h>
#define debug 0
using namespace std;
inline int read(){
	int res=0;
	bool zf=0;
	char c;
	while(((c=getchar())<'0'||c>'9')&&c!='-');
	if(c=='-')zf=1;
	else res=c-'0';
	while((c=getchar())>='0'&&c<='9')res=(res<<3)+(res<<1)+c-'0';
	return (zf?-res:res);
}
int bel[800005];
int col[400005];
vector<int>lsh;
vector<int>G[400005];
int dep[400005],fa[400005],size[400005],son[400005],top[400005];
vector<int>Euler;
int fir[400005],sec[400005],tot; 
void dfs1(int now){
	fir[now]=(++tot);
	Euler.push_back(now);
	size[now]=1;
	for(register int i=0;i<G[now].size();++i){
		int v=G[now][i];
		if(dep[v])continue;
		dep[v]=dep[now]+1;
		fa[v]=now;
		dfs1(v);
		size[now]+=size[v];
		if(size[v]>size[son[now]]){
			son[now]=v;
		}
	}
	sec[now]=(++tot);
	Euler.push_back(now);
	return;
}
void dfs2(int now){
	if(!son[now])return;
	top[son[now]]=now;
	dfs2(son[now]);
	for(register int i=0;i<G[now].size();++i){
		int v=G[now][i];
		if(v==fa[now]||v==son[now])continue;
		dfs2(top[v]=v);
	}
	return; 
}
inline int lca(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	return x;
}
struct op{
	int l,r,id;
	bool In;
}ask[1000005];
inline bool cmp(op x,op y){
	return (bel[x.l]^bel[y.l]?bel[x.l]<bel[y.l]:x.r<y.r);
}
int cnt[400005];
bool ds[400005];
int ans[1000005];
signed main(){
	int n=read(),m=read();
	for(register int i=1;i<=n;++i){
		col[i]=read();
		lsh.push_back(col[i]);
	}
	sort(lsh.begin(),lsh.end());
	lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());
	for(register int i=1;i<=n;++i){
		col[i]=lower_bound(lsh.begin(),lsh.end(),col[i])-lsh.begin()+1;
	}
	if(debug){
		puts("lsm:");
		for(register int i=1;i<=n;++i){
			printf("%d ",col[i]);
		}
		putchar('\n');
	}
	for(register int i=1;i<n;++i){
		int x=read(),y=read();
		G[x].push_back(y),G[y].push_back(x); 
	}
	Euler.push_back(-1);
	dfs1(dep[1]=1);
	dfs2(top[1]=1);
	if(debug){
		puts("Euler:");
		for(register int i=1;i<=tot;++i){
			printf("%d ",Euler[i]);
		}
		putchar('\n');
		puts("First and second:");
		for(register int i=1;i<=n;++i){
			printf("first:%d,second:%d\n",fir[i],sec[i]);
		}
	}
	for(register int i=1;i<=m;++i){
		int p=read(),q=read();
		if(fir[p]>fir[q])swap(p,q);
		int l=lca(p,q);
		if(l==p)ask[i].l=fir[p],ask[i].r=fir[q],ask[i].In=1;
		else ask[i].l=sec[p],ask[i].r=fir[q],ask[i].In=0;
		ask[i].id=i;
	}
	int size=sqrt(n);
	for(register int i=1;i<=2*n;++i){
		bel[i]=(i-1)/size+1;
	}
	sort(ask+1,ask+m+1,cmp);
	if(debug){
		puts("Ask:");
		for(register int i=1;i<=m;++i){
			printf("id #%d: left:%d, right:%d, in:%s\n",ask[i].id,ask[i].l,ask[i].r,(ask[i].In?"true":"false"));
		}
	}
	int l=1,r=0,nowans=0;
	for(register int i=1;i<=m;++i){
		while(l<ask[i].l){
			if(!ds[Euler[l]]&&!cnt[col[Euler[l]]])++nowans;
			if(ds[Euler[l]]&&cnt[col[Euler[l]]]==1)--nowans;
			ds[Euler[l]]^=1; 
			cnt[col[Euler[l]]]+=(ds[Euler[l]]?1:-1);
			l++;}
		while(l>ask[i].l){
			if(!ds[Euler[l-1]]&&!cnt[col[Euler[l-1]]])++nowans;
			if(ds[Euler[l-1]]&&cnt[col[Euler[l-1]]]==1)--nowans;
			ds[Euler[--l]]^=1;
			cnt[col[Euler[l]]]+=(ds[Euler[l]]?1:-1);
		}
		while(r<ask[i].r){
			if(!ds[Euler[r+1]]&&!cnt[col[Euler[r+1]]])++nowans;
			if(ds[Euler[r+1]]&&cnt[col[Euler[r+1]]]==1)--nowans;
			ds[Euler[++r]]^=1;
			cnt[col[Euler[r]]]+=(ds[Euler[r]]?1:-1);
		}
		while(r>ask[i].r){
			if(!ds[Euler[r]]&&!cnt[col[Euler[r]]])++nowans;
			if(ds[Euler[r]]&&cnt[col[Euler[r]]]==1)--nowans;
			ds[Euler[r]]^=1;
			cnt[col[Euler[r]]]+=(ds[Euler[r]]?1:-1);
			r--;}
		ans[ask[i].id]=nowans+!ask[i].In;
	}
	for(register int i=1;i<=m;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}
2020/8/28 20:48
加载中...