来自蒟蒻XXJ的做题记录
这个东西 $==$
我能说我看了很久的证明都没有看懂吗w 但是PhoenixEclipse巨巨好像想出了证明 %%%%% @PhoenixEclipse【也不知道会不会蓝
首先 Burnsid引理 大概都知道w 不知道的去问问度娘
然后呢我在考虑证明的时候好像就考虑到了w如果这个元素对于这种置换是个不动点,那么一定有,在这个元素里面w置换所成的环里面的东西都是一样的【绕
说简单一点w就是怎么转都是不会改变这个里面的东西的顺序的w才叫不动点w不改变顺序w必须里面都相等w
然后就是怎么把这三种颜色的东西给放到里面去了w这个东西写一个DP算一下方案数就好了w很简单的背包 然后为了空间节省w再像01背包那样优化掉一维空间就好了w
于是,出现吧代码君!@代码君【我管你蓝不蓝
#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
ll in(){
ll a(0);char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar();
return a;
}
void extgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;y=0;
return;
}
else{
extgcd(b,a%b,y,x);
y-=(a/b)*x;
}
}
ll rev(ll a,ll m){
ll x,y;
extgcd(a,m,x,y);
return (x%m+m)%m;
}
ll n,m,MOD;
ll s1,s2,s3;
ll cyc[64][64],top[64],dp[32][32][32];
ll cycle[64],ans;
bool vis[64];
void input(){
s1=in();s2=in();s3=in();m=in();MOD=in();
n=s1+s2+s3;
for(ll i=0;i<m;i++){
mem(vis,0);
for(ll j=1;j<=n;j++) cycle[j]=in();
for(ll j=1;j<=n;j++){
if(vis[j]) continue;
ll len(0),now=j;
while(!vis[now]){
++len;vis[now]=1;
now=cycle[now];
}
cyc[i][++top[i]]=len;
}
}
for(ll i=1;i<=n;i++) cyc[m][i]=1;
top[m]=n;
}
ll domicp(ll now){
mem(dp,0);
dp[0][0][0]=1;
for(ll h=1;h<=top[now];++h){
ll del=cyc[now][h];
for(ll i=s1;i>=0;--i)for(ll j=s2;j>=0;--j)for(ll k=s3;k>=0;--k){
if(!i&&!j&&!k) continue;
if(i-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i-del][j][k])%MOD;
if(j-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i][j-del][k])%MOD;
if(k-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i][j][k-del])%MOD;
}
}
return dp[s1][s2][s3];
}
void xxj(){
ll sum(0);
for(ll i=0;i<=m;i++)
sum=(sum+domicp(i))%MOD;
ll revv=rev((m+1),MOD);
ans=revv*sum;ans%=MOD;
}
void output(){
printf("%lld\n",ans);
}
int main(){
input();
xxj();
output();
return 0;
}
PS:自从代码君被我毁了颜值就再也不爱我了