Schreier–Sims 算法

好看的实现。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=105;
int n,q;
struct perm{int p[maxn];};
perm operator *(perm a,perm b){
	perm c;
	for(int i=1;i<=n;i++)c.p[i]=a.p[b.p[i]];
	return c;
}
perm inv(perm a){
	perm c;
	for(int i=1;i<=n;i++)c.p[a.p[i]]=i;
	return c;
}
vector<perm> R[maxn],S[maxn];
int nrm[maxn][maxn];
perm e;
bool pd(perm a,int N=n){
	int m=N;
	while(m>1){
		if(nrm[m][a.p[m]]==-1)return 0;
		a=inv(R[m][nrm[m][a.p[m]]])*a;
		--m;
	}
	return 1;
}
void exins(perm a,int N);
void ins(perm a,int N);
void exins(perm a,int N){
	int &g=nrm[N][a.p[N]];
	if(g==-1){
		g=R[N].size();
		R[N].push_back(a);
		vector<perm> d;
		for(auto s:S[N])d.push_back(s*a);
		for(auto p:d)exins(p,N);
	}else{
		a=inv(R[N][g])*a;
		ins(a,N-1);
	}
}
void ins(perm a,int N){
	if(pd(a,N))return ;
	S[N].push_back(a);
	vector<perm> d;
	for(auto t:R[N])d.push_back(a*t);
	for(auto p:d)exins(p,N);
}
int calc(){
	int res=1;
	for(int i=1;i<=n;i++)res=res*(int)R[i].size();
	return res;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	memset(nrm,-1,sizeof(nrm));
	cin>>n>>q;
	for(int i=1;i<=n;i++)e.p[i]=i;
	for(int i=1;i<=n;i++)nrm[i][i]=0,R[i].push_back(e);
	for(int i=1;i<=q;i++){
		perm a;for(int j=1;j<=n;j++)cin>>a.p[j];
		ins(a,n);
	}	
	cout<<calc()<<endl;
	return 0;
}
posted @ 2024-12-17 21:34  British_Union  阅读(5)  评论(0编辑  收藏  举报