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;
}
YJX AK IOI