ACM vfk 式名字重排
题目链接
菜鸡第一次写博客 很简单一道题
题意: 对所有数组里的数重排列 共有多少种排列方式(其本身也算一种)
题解:如果每个数字没有重复 就有N的阶乘种 若有重复直接除它重复次数的阶乘
问题就出现在这里 比赛时候忘了逆元这个东西 一直直接除 导致wa了九次 长了记性
逆元 当出现大数除法并且需要模的时侯使用 除就相当于乘以它的逆元
更详细的逆元的介绍放在这大佬的讲解
自行查看 不是我可以马上都学会并且转述的
!!!模的时侯一定记得所有大数都要模 不然就会WA
AC 代码
#include <iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const long int MOD=1e9+7;
ll quickpow(ll a, ll n)
{
ll ans = 1;
while(n)
{
if(n&1)
{
ans = (ans * a) % MOD;
}
a = (a * a) % MOD;
n >>= 1;
}
return ans;
}
int main ()
{
int n,k;
scanf("%d%d",&n,&k);
int p[n+5];
ll a[n+5];
int time[k+5];
memset(time,0,sizeof(time));
for(int i=0; i<n; i++)
{
scanf("%d",&p[i]);
time[p[i]]++;
}
a[1]=1;
for(int i=2; i<=n; i++)
{
a[i]=a[i-1]*i%MOD;
}
ll ans=a[n];
ll kk=1;
for(int i=0; i<k; i++)
{
if(time[i]>1)
kk=kk*a[time[i]]%MOD; //这里也要模啊!!!
}
ans= ans%MOD*quickpow(kk,MOD-2)%MOD;
printf("%lld\n",ans);
return 0;
}