邀请各位欣赏 11 个 dfs 的代码
  • 板块灌水区
  • 楼主wukaichen888
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/2/24 17:13
  • 上次更新2024/2/24 17:19:59
查看原帖
邀请各位欣赏 11 个 dfs 的代码
723238
wukaichen888楼主2024/2/24 17:13

题面

SAM 里面塞了 2 个 dfs

我代码实现真的好垃圾啊,调了好久

const ll N=2e5+5;
int n,m,K;
ll ans,res;
char s[N],t[N];
struct SAM{
	int qwq,las=1,tot=1,f[N],seg[N];
	int len[N],fa[N],ch[N][27],ch2[N][27],siz[N],pos[N];
	char tc[N];
	vector<int>v[N];
	void add(int c,int id){
		int p=las,np=las=++tot;
		len[np]=len[p]+1;
		seg[id]=np,siz[np]=1,pos[np]=id;
		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
		if(!p) fa[np]=1;
		else{
			int q=ch[p][c];
			if(len[q]==len[p]+1) fa[np]=q;
			else{
				int nq=++tot;
				for(int i=0;i<26;i++) ch[nq][i]=ch[q][i];
				fa[nq]=fa[q];
				fa[np]=fa[q]=nq;
				len[nq]=len[p]+1;
				for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
			}
		}
	}
	void dfs(int x){
		for(int i=0;i<v[x].size();i++){
			dfs(v[x][i]);
			siz[x]+=siz[v[x][i]];
			if(!pos[x]) pos[x]=pos[v[x][i]]; 
		}
		ch2[fa[x]][tc[pos[x]-len[fa[x]]]-'a']=x;
	}
	void dfs2(int x){
		for(int i=0;i<v[x].size();i++){
			f[v[x][i]]+=f[x];
			dfs2(v[x][i]);
		}
	}
	void pre(){
		for(int i=1;i<=qwq;i++) add(tc[i]-'a',i);
		for(int i=2;i<=tot;i++) v[fa[i]].push_back(i);
		dfs(1);
//		for(int i=1;i<=tot;i++) printf("%d ",fa[i]);
//		puts("");
//		for(int i=1;i<=tot;i++) printf("%d ",siz[i]);
//		puts("");
//		for(int i=1;i<=qwq;i++) printf("%d ",seg[i]);
//		puts("");
	}
	int get(int x,int y,char c){
		if(len[x]==y) x=ch2[x][c-'a'];
		else{
			if(tc[pos[x]-y]!=c) x=0;
		}
		return x;
	}
}Z,F;
int now,siz[N],maxx[N],rt,tot1;bool vis[N];vector<int>v[N];
void dfs1(int x,int fa){
	siz[x]=1,tot1++,maxx[x]=0;
	for(int i=0;i<v[x].size();i++)
		if(v[x][i]!=fa&&!vis[v[x][i]]){
			dfs1(v[x][i],x),siz[x]+=siz[v[x][i]];
			maxx[x]=max(maxx[x],siz[v[x][i]]);
		}
}
void dfs2(int x,int fa){
	for(int i=0;i<v[x].size();i++)
		if(v[x][i]!=fa&&!vis[v[x][i]])
			dfs2(v[x][i],x);
	maxx[x]=max(maxx[x],tot1-siz[x]);
	if(maxx[x]<maxx[rt]) rt=x;
}
int getrt(int x){tot1=0,rt=x;dfs1(x,0),dfs2(x,0);return rt;}
void dfs3(int to,int x,int fa,bool flag){
	flag|=(x==now);
	if(!to) return ;
	if(flag) res+=Z.siz[to];
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs3(Z.ch[to][s[v[x][i]]-'a'],v[x][i],x,flag);
	}
}
void dfs4(int x,int fa){
	dfs3(Z.ch[1][s[x]-'a'],x,0,0);
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs4(v[x][i],x);
	}
}
void dfs5(int to,int y,int x,int fa){
	if(!to) return ;
	Z.f[to]++;
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs5(Z.get(to,y,s[v[x][i]]),y+1,v[x][i],x);
	}
}
void dfs6(int to,int y,int x,int fa){
	if(!to) return ;
	F.f[to]++;
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs6(F.get(to,y,s[v[x][i]]),y+1,v[x][i],x);
	}
}
void dfs7(int to,int x,int fa){
//	printf("7 %d %d %d\n",x,to,Z.siz[to]);
	if(!to) return ;
	res+=Z.siz[to];
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs7(Z.ch[to][s[v[x][i]]-'a'],v[x][i],x);
	}
}
void dfs8(int to,int x,int fa){
//	printf("8 %d %d\n",x,to);
	if(!to) return ;
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(v[x][i]==now){
			dfs7(Z.ch[Z.ch[to][s[now]-'a']][s[x]-'a'],x,now);
		}
		if(vis[v[x][i]]) continue;
		dfs8(Z.ch[to][s[v[x][i]]-'a'],v[x][i],x);
	}
}
void dfs9(int x,int fa){
	dfs8(Z.ch[1][s[x]-'a'],x,0);
	for(int i=0;i<v[x].size();i++){
		if(v[x][i]==fa) continue;
		if(vis[v[x][i]]) continue;
		dfs9(v[x][i],x);
	}
}
ll solve1(int x){
	res=0; dfs4(x,0);
	return res;
}
ll solve2(int x){
	for(int i=0;i<=Z.tot;i++) Z.f[i]=0;
	for(int i=0;i<=F.tot;i++) F.f[i]=0;
	res=0;
	dfs5(Z.ch[1][s[x]-'a'],1,x,0);
	dfs6(F.ch[1][s[x]-'a'],1,x,0);
	Z.dfs2(1);
	F.dfs2(1);
//	for(int i=1;i<=m;i++) printf("%d ",Z.f[Z.seg[i]]);
//	puts("");
//	for(int i=1;i<=m;i++) printf("%d ",F.f[F.seg[i]]);
//	puts("");
	for(int i=1;i<=m;i++) res+=(ll)Z.f[Z.seg[i]]*F.f[F.seg[m-i+1]];
	return res;
}
ll solve3(int x){
	res=0; dfs9(x,0);
	return res;
}
ll solve4(int x,int fa){
	for(int i=1;i<=Z.tot;i++) Z.f[i]=0;
	for(int i=1;i<=F.tot;i++) F.f[i]=0;
	res=0;
	dfs5(Z.ch[Z.ch[1][s[x]-'a']][s[fa]-'a'],2,x,fa);
	dfs6(F.ch[F.ch[1][s[x]-'a']][s[fa]-'a'],2,x,fa);
	Z.dfs2(1);
	F.dfs2(1);
//	for(int i=1;i<=m;i++) printf("%d ",Z.f[i]);
//	puts("");
//	for(int i=1;i<=m;i++) printf("%d ",F.f[i]);
//	puts("");
	for(int i=1;i<=m;i++) res+=(ll)Z.f[Z.seg[i]]*F.f[F.seg[m-i+1]];
	return res;
}
void build(int x){
	dfs1(x,0);
//	printf("%d::\n",x);
	now=x;
	if(siz[x]<=K){
		ans+=solve1(x);
//		printf("%d\n",solve1(x));
	}
	else{
		ans+=solve2(x);
//		printf("%d\n",solve2(x));
		vis[x]=1;
		for(int i=0;i<v[x].size();i++)
			if(!vis[v[x][i]]){
				if(siz[v[x][i]]<=K){
//					printf("%d %d\n",v[x][i],solve3(v[x][i]));
					ans-=solve3(v[x][i]);
				}
				else{
//					printf("%d %d\n",v[x][i],solve4(v[x][i],x));
					ans-=solve4(v[x][i],x);
				}
			}
	} 
	vis[x]=1;
	for(int i=0,y;i<v[x].size();i++)
		if(!vis[v[x][i]]){
			y=getrt(v[x][i]);
			build(y);
		}
}
2024/2/24 17:13
加载中...