1 条题解
-
2
题意
已知一个有 个 , 个 的序列。
令 表示序列 的最大前缀和。
即
已知 , 求所有可以组成的序列 , 之和是多少。
答案对 取模。
注意模数。
题解
首先考虑将答案分解,令 表示 的序列 的方案数。
那么
问题转化为算方案数。
将问题放到平面直角坐标系上, 就是向左上走一格, 就是向右下走一格。
如图就是序列 。
统计 实际就是统计有多少条折线满足进过直线 。
如图,经过红线的折线个数就是 。
那么如何求呢?
如图,用求卡特兰数的套路,直接将第一次经过直线的点后面的部分轴对称即可。
注意特判 的情况。
#include<bits/stdc++.h> using namespace std; const int N=5005,mod=998244853; int jie[N],ni[N],ans,n,m; int kuai(int a,int b){ int ans=1; for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod; return ans; } void work(int maxn){ jie[0]=ni[0]=1; for(int i=1;i<=maxn;i++)jie[i]=1ll*jie[i-1]*i%mod; ni[maxn]=kuai(jie[maxn],mod-2); for(int i=maxn-1;i;i--)ni[i]=1ll*ni[i+1]*(i+1)%mod; } int C(int n,int m){return 1ll*jie[n]*ni[m]%mod*ni[n-m]%mod;}//组合数的预处理 int main(){ std::ios::sync_with_stdio(false); cin>>n>>m; work(5000); if(n-m>0)ans=1ll*C(n+m,n)*(n-m)%mod;//特判情况 for(int i=max(1,n-m+1);i<=n;i++)ans=(ans+C(n+m,n-i))%mod;//统计答案 cout<<ans; }
- 1
信息
- ID
- 1760
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者