卧薪尝胆,厚积薄发。
饼干
Date: Tue Oct 16 16:49:11 CST 2018
In Category:
NoCategory
Description:
$A$
物品价值为
$a$
,
$B$
物品价值为
$b$
,
$C$
物品价值为
$a+b$
,
$n$
个位置可以放也可以不放,求价值和为
$k$
的摆放方案数。
$1\leqslant n\leqslant 10^7$
Solution:
$C$
物品价值
$a+b$
考虑怎么处理,发现可以看成先随便放
$A$
,然后随便放
$B$
,他们都放的位置看成放
$C$
,所以如果放了
$a$
个
$A$
,那么方案数就是
$C_n^a\times C_n^\frac{K-a\times A}B$
,所以枚举
$a$
预处理阶乘和逆元求组合数就行了,注意有数为
$0$
时有很多特判。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
int n;
typedef long long ll;
ll A,B,K;
#define MAXN 10000010
#define MOD 998244353
int fac[MAXN],inv[MAXN];
int power(int a,int b)
{
int res = 1;
while(b > 0)
{
if(b & 1)res = 1ll * res * a % MOD;
a = 1ll * a * a % MOD;
b = b >> 1;
}
return res;
}
int C(int n,int m)
{
return 1ll * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
int main()
{
freopen("biscuits.in","r",stdin);
freopen("biscuits.out","w",stdout);
fac[0] = 1;for(register int i = 1;i < MAXN;++i)fac[i] = 1ll * fac[i - 1] * i % MOD;
inv[MAXN - 1] = power(fac[MAXN - 1],MOD - 2);
inv[0] = 1;for(register int i = MAXN - 2;i >= 1;--i)inv[i] = 1ll * inv[i + 1] * (i + 1) % MOD;
scanf("%d%lld%lld%lld",&n,&A,&B,&K);
if(A == 0 && B == 0)
{
if(K == 0)
{
int res = 1;
for(int i = 1;i <= n;++i)res = 1ll * res * 4 % MOD;
cout << res << endl;
return 0;
}
else
{
puts("0");
return 0;
}
}
if(A == 0)
{
if(K == 0)
{
int res = 1;
for(int i = 1;i <= n;++i)res = res * 2 % MOD;
cout << res << endl;
return 0;
}
else if(K % B != 0 || K / B > n)
{
puts("0");
return 0;
}
else
{
int res = C(n,K / B);
for(int i = 1;i <= n;++i)res = res * 2 % MOD;
cout << res << endl;
return 0;
}
}
if(B == 0)
{
if(K == 0)
{
int res = 1;
for(int i = 1;i <= n;++i)res = res * 2 % MOD;
cout << res << endl;
return 0;
}
else if(K % A != 0 || K / A > n)
{
puts("0");
return 0;
}
else
{
int res = C(n,K / A);
for(int i = 1;i <= n;++i)res = res * 2 % MOD;
cout << res << endl;
return 0;
}
}
int ans = 0;
for(int a = 0;a <= n;++a)
{
if((K - a * A) % B == 0)
{
ll b = (K - a * A) / B;
if(b > n)continue;
if(b < 0)continue;
ans = (ans + 1ll * C(n,a) * C(n,b)) % MOD;
}
}
cout << ans << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
In tag:
数学-组合数
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡