http://lx.lanqiao.cn/problem.page?gpid=T397
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
输入格式
输入一行,包含两个整数n, m。
输出格式
输出一行,包含求得的值,由于答案可能非常大,请输出此公式除以987654321的余数。
样例输入
3 1
样例输出
162
数据规模和约定
1<=m<=n<=10^7。
思路:https://blog.dotcpp.com/a/56426
#include<iostream>
#include<ctime>
#define ll long long
using namespace std;
const int N = 10000000 + 5;
const int mod = 987654321;
ll prime[N];
ll stu[N];
ll cnt;
void get_prime(ll n)
{
for(int i=2; i<=n; i++)
{
if(!stu[i]) prime[cnt++] = i;
for(int j=0; prime[j] * i <= n; j++)
{
stu[prime[j]*i] = 1;
if(i % prime[j] == 0) break;
}
}
}
ll ksm(ll a, ll b)
{
ll ans = 1;
while(b)
{
if(b & 1) ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
ll f(ll a, ll b)//求a的阶乘里有多少个b如f(5,2)值为3(2,4)
{
ll ans = 0;
while(a)
{
ans += a /= b;
}
return ans;
}
ll c(ll n, ll m)
{
ll ans = 1;
for(int i=0; i<cnt && prime[i]<=n; i++)
{
ans = ans * ksm(prime[i], f(n,prime[i]) - f(m,prime[i]) - f(n-m,prime[i])) % mod;
}
return ans;
}
ll cal(int n)
{
ll ans = 1;
for(int i=1; i<=n; i++)
{
ans *= i;
}
return ans;
}
int main()
{
ll n,m;
cin>>n>>m;
get_prime(n);
ll cnm = c(n,m);
ll sum = 0;
if(n >= 3)
{
sum = ksm(2,n-3) * (4 * n % mod + n * (n - 1) % mod * (n + 4) % mod) % mod;
}
for(int i=1; i <= n && n < 3; i++)
{
sum += cal(n)/cal(i)/cal(n-i) * i * i * i % mod;
}
cout<< cnm * sum % mod<<endl;
return 0;
}