链接:
https://www.nowcoder.com/acm/contest/113/A
来源:牛客网
来源:牛客网
题目描述
给出四堆石子,石子数分别为a,b,c,d。规定每次只能从堆顶取走石子,问取走所有石子的方案数。
输入描述:
在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数
输出描述:
输出一个整数表示答案,答案对109+7取模
翻译过来就是有4个队的人 人数可能不同 站成一个大队伍一共用多少种排列方式
四堆石子看作4队人 4个队的人排成一排的方案数量 首先总人数全排列,然后去重
因为每个队伍里面的人看作是一样的无区别的
费马小定理
在模为素数p的情况下,有费马小定理
a^(p-1)=1(mod p)
那么a^(p-2)=a^-1(mod p)
也就是说a的逆元为a^(p-2)
而在模不为素数p的情况下,有欧拉定理
a^phi(m)=1(mod m) (a⊥m)
同理a^-1=a^(phi(m)-1)
因此逆元x便可以套用快速幂求得了x=a^(phi(m)-1)
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mset(a,b) memset(a,b,sizeof(a))
#define sz size()
#define cl clear()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923078164
typedef long long ll;
typedef pair<int,int> pr;
const int inf = 99999999;
const double eps = 1e-8;
const int dir4[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
const int dir8[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int mod = 1e9 + 7;
//快速幂
ll quickPow(ll a,ll b)
{
ll res = 1;
while(b)
{
if(b & 1)
{
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}
ll inv(ll x)
{
ll res = 1;
res = quickPow(x,mod-2) % mod;
return res;
}
ll jc(ll a)
{
ll res = 1;
for(int i = 1;i <= a;i ++)
res = res * i % mod;
return res;
}
int main()
{
ll a, b, c, d;
cin >> a >> b >> c >> d;
ll sum = jc(a+b+c+d);
cout << sum * inv(jc(a))% mod* inv(jc(b))% mod * inv(jc(c)) % mod* inv(jc(d)) % mod;
return 0;
}