luogu P1446 [HNOI2008]Cards
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100;
int R,B,G,m,M,a[N],n,cnt,b[N],vis[N],f[N][N][N],sum[N];
void init()
{
scanf("%d %d %d %d %d",&R,&B,&G,&m,&M);
n=R+B+G;
}
int ksm(int a,int b)
{
int res=1;
while(b)
{
if(b&1)
res=1LL*res*a%M;
b>>=1,a=1LL*a*a%M;
}
return res;
}
int C(int x,int y)
{
int A=1,B=1;
for (int i=y+1;i<=x;i++)
A=1LL*A*i%M;
for (int i=1;i<=x-y;i++)
B=1LL*B*i%M;
A=1LL*A*ksm(B,M-2)%M;
return A;
}
void dfs(int x,int now)
{
vis[x]=1;
if(vis[a[x]])
{
b[++cnt]=now;
return;
}
dfs(a[x],now+1);
}
void add(int &x,int y)
{
x=x+y>M?x+y-M:x+y;
}
void work()
{
int ans=1LL*C(n,R)*C(n-R,B)%M;
for (int _=1;_<=m;_++)
{
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(vis,0,sizeof(vis)),cnt=0;
for (int i=1;i<=n;i++)
if(!vis[i])
dfs(i,1);
// for (int i=1;i<=cnt;i++)
// printf("%d ",b[i]);puts("");
for (int i=1;i<=cnt;i++)
sum[i]=sum[i-1]+b[i];
for (int i=0;i<=cnt;i++)
for (int j=0;j<=R;j++)
for (int k=0;k<=B;k++)
f[i][j][k]=0;
f[0][0][0]=1;
for (int i=0;i<cnt;i++)
for (int j=0;j<=R;j++)
for (int k=0;k<=B;k++)
if(f[i][j][k])
{
if(j+b[i+1]<=R)
add(f[i+1][j+b[i+1]][k],f[i][j][k]);
if(k+b[i+1]<=B)
add(f[i+1][j][k+b[i+1]],f[i][j][k]);
if(sum[i]-j-k+b[i+1]<=G)
add(f[i+1][j][k],f[i][j][k]);
}
add(ans,f[cnt][R][B]);
}
ans=1LL*ans*ksm(m+1,M-2)%M;
printf("%d\n",ans);
}
int main()
{
init();
work();
return 0;
}
由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!