题目描述
通过分析,最终将原问题转化为数学问题,即求解
$C_n^s * 2^ {n-s}$
求解组合数
数据范围:
$1≤n≤2000$
$0≤s≤2000$
运用定义法计算组合数(模板题: 888. 求组合数 IV )
计算过程:
- 线性法筛质数
- 运用组合数公式求出分子分母中分别含有的质因数个数
- 运用除法性质解出所求组合数中各质因数个数,然后将其相乘
C++ 代码
// c[n][s] * (2 ^ (n - s))
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 2010, mod = 1e9 + 7;
int primes[N], cnt;
bool st[N];
int powers[N];
int n, s;
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i])
{
primes[cnt++] = i;
for(int j = i * 2; j <= n; j += i)
st[j] = true;
}
}
}
int get(int x, int p) //求解x里有多少个p
{
int s = 0;
while(x)
{
s += x / p;
x /= p;
}
return s;
}
int main()
{
scanf("%d%d", &n, &s);
get_primes(n);
for(int i = 0; i < cnt; i++)
{
int p = primes[i];
powers[i] += get(n, p) - get(s, p) - get(n - s, p);
}
int res = 1;
for(int i = 0; i < cnt; i++)
{
int p = primes[i];
while(powers[i]--) res = (LL)res * p % mod;
}
for(int i = 0; i < n - s; i++) res = (LL)res * 2 % mod;
printf("%d\n", res);
return 0;
}