CCPC威海2021M. 810975
Posted solemntee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCPC威海2021M. 810975相关的知识,希望对你有一定的参考价值。
题意
进行了 n n n场比赛,获胜 m m m局,其中最长连胜是 k k k,问有多少种情况。
题解
考虑
a
n
s
k
ans_k
ansk为:进行了
n
n
n场比赛,获胜
m
m
m局,其中最长连胜大于等于
k
k
k,问有多少种情况。
因为有
n
−
m
n-m
n−m个负场,所以考虑把每个负场的周围当成空然后插入胜场。
枚举
i
i
i为连续长度大于等于
k
k
k的胜场次,枚举这些连续胜场所在的空,数量是
(
i
n
−
m
+
1
)
(^n-m+1_\\ \\ \\ \\ \\ \\ i)
( in−m+1),然后接下来的任意分配就可以,方案数是
(
n
−
m
n
−
i
k
)
(^n-ik_n-m)
(n−mn−ik),故
a
n
s
k
=
∑
i
=
1
m
−
i
∗
k
>
=
0
(
−
1
)
i
+
1
(
i
n
−
m
+
1
)
(
n
−
m
n
−
i
k
)
ans_k=\\sum_i=1^m-i*k>=0(-1)^i+1(^n-m+1_\\ \\ \\ \\ \\ \\ i)(^n-ik_n-m)
ansk=i=1∑m−i∗k>=0(−1)i+1( in−m+1)(n−mn−ik)
最后输出 a n s k + 1 − a n s k ans_k+1-ans_k ansk+1−ansk即可
特别的,如果考虑生成函数,枚举每一个空里面的胜场个数可以用多项式快速幂来做,最大胜场小于等于
k
k
k的方案数可以由
a
n
s
k
=
(
1
+
x
2
+
.
.
+
x
k
)
n
−
m
+
1
=
(
1
−
x
k
+
1
1
−
x
)
n
−
m
+
1
ans_k=(1+x^2+..+x^k)^n-m+1= (\\frac 1-x^k+1 1-x )^n-m+1
ansk=(1+x2+..+xk)n−m+1=(1−x1−xk+1)n−m+1
中次数为m的项系数来表示,然后答案就是
a
n
s
k
−
a
n
s
k
−
1
ans_k-ans_k-1
ansk−ansk−1
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=998244353;
ll poww(ll a,ll b)
ll t=1;
while(b)
if(b&1)t=t*a%mod;
a=a*a%mod;
b>>=1;
return t;
ll P1[300005],P2[300005];
void init()
P1[0]=P2[0]=1;
for(int i=1;i<=300000;i++)P1[i]=P1[i-1]*i%mod;
P2[300000]=poww(P1[300000],mod-2);
for(int i=299999;i>=1;i--)P2[i]=P2[i+1]*(i+1)%mod;
ll C(ll n,ll m)
return P1[n]*P2[m]%mod*P2[n-m]%mod;
int main()
init();
long long n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
ll ans=0;
if(k==0)
printf("%d\\n",m==0);
return 0;
for(ll i=1;i*k<=m;i++)
if(i&1)ans=(ans+C(n-m+1,i)*C(n-i*k,n-m)%mod)%mod;
else ans=(ans-C(n-m+1,i)*C(n-i*k,n-m)%mod)%mod;
// printf("ans=%lld\\n",ans);
k++;
for(ll i=1;i*k<=m;i++)
if(i&1)ans=(ans-C(n-m+1,i)*C(n-i*k,n-m)%mod)%mod;
else ans=(ans+C(n-m+1,i)*C(n-i*k,n-m)%mod)%mod;
printf("%lld",(ans%mod+mod)%mod);
return 0;
我也不知道为什么这么傻 B B B的题目比赛的时候会卡?
以上是关于CCPC威海2021M. 810975的主要内容,如果未能解决你的问题,请参考以下文章