LGP3244题解
Burnside引理:
\(X\) 在群 \(G\) 作用下的等价类总数等于每一个 \(g\) 作用于 \(X\) 的不动点的算数平均值。
对于此题,\(X\) 代表每一种染色方案,\(G\) 则代表每一个排列(置换)。
我们需要计算的是,对于每一个置换,有多少种染色方法使得置换后颜色仍然相同。
众所周知置换是一车环。变成计算有多少种染色方法使得每个环的颜色都相同。
因为只有三种颜色,且数量均不超过 \(20\),直接大力三维背包。
复杂度 \(O(m20^3)\),可以通过。
别忘了我们还有一个置换:\(p[i]=i\)。
#include
typedef unsigned ui;
const ui M=25;
ui n,m,s1,s2,s3,mod,p[M*3],dp[M][M][M];
inline ui DP(ui*p){
static ui m,w[M*3];static bool vis[M*3];
for(ui i=1;i<=n;++i)vis[i]=false;m=0;
for(ui i=0;i<=s1;++i)for(ui j=0;j<=s2;++j)for(ui k=0;k<=s3;++k)dp[i][j][k]=0;dp[0][0][0]=1;
for(ui i=1;i<=n;++i)if(!vis[i]){
w[++m]=1;ui now=p[i];
while(now!=i)vis[now]=true,++w[m],now=p[now];
}
for(ui x=1;x<=m;++x){
for(ui i=s1;~i;--i)for(ui j=s2;~j;--j)for(ui k=s3;~k;--k){
if(w[x]<=i)dp[i][j][k]+=dp[i-w[x]][j][k];
if(w[x]<=j)dp[i][j][k]+=dp[i][j-w[x]][k];
if(w[x]<=k)dp[i][j][k]+=dp[i][j][k-w[x]];
dp[i][j][k]%=mod;
}
}
return dp[s1][s2][s3];
}
signed main(){
ui sum(0);
scanf("%u%u%u%u%u",&s1,&s2,&s3,&m,&mod);n=s1+s2+s3;
for(ui i=1;i<=m;++i){
for(ui i=1;i<=n;++i)scanf("%u",p+i);sum+=DP(p);
}
for(ui i=1;i<=n;++i)p[i]=i;sum+=DP(p);
for(ui i=1;i