题目:BZOJ1856.
题目大意:给定
n
n
n个
1
1
1和
m
m
m个
−
1
-1
−1,求组成的序列每一个前缀和都不小于
0
0
0的方案数.
1
≤
n
,
m
≤
1
0
6
1\leq n,m\leq 10^6
1≤n,m≤106.
首先这个问题很像经典的Catalan数问题,但这里 1 1 1和 − 1 -1 −1的个数是不等的.
上面的Catalan数链接的问题4拓展已经把这个问题讲的很清楚了这里不讲了,直接上结论答案为:
{
0
n
<
m
C
n
+
m
m
−
C
n
+
m
m
−
1
n
≥
m
\left\{\begin{matrix} 0&n<m\\ C_{n+m}^{m}-C_{n+m}^{m-1}&n\geq m \end{matrix}\right.
{0Cn+mm−Cn+mm−1n<mn≥m
有了结论后就是一道简单题了.
时间复杂度 O ( n ) O(n) O(n).
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=1000000,mod=20100403;
int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
int sub(int a,int b){return a-b<0?a-b+mod:a-b;}
int mul(int a,int b){return (LL)a*b%mod;}
int sqr(int a){return a=(LL)a*a%mod;}
void sadd(int &a,int b){a=add(a,b);}
void ssub(int &a,int b){a=sub(a,b);}
void smul(int &a,int b){a=mul(a,b);}
void ssqr(int &a){a=sqr(a);}
int n,m,inv[N*2+9];
void Pre_inv(int n){
inv[1]=1;
for (int i=2;i<=n+m;++i) inv[i]=mul(mod-mod/i,inv[mod%i]);
}
int Calc_C(int n,int m){
int res=1;
for (int i=1;i<=n;++i) smul(res,i);
for (int i=1;i<=m;++i) smul(res,inv[i]);
for (int i=1;i<=n-m;++i) smul(res,inv[i]);
return res;
}
Abigail into(){
scanf("%d%d",&n,&m);
}
Abigail work(){
Pre_inv(n);
}
Abigail outo(){
printf("%d\n",n<m?0:sub(Calc_C(n+m,m),Calc_C(n+m,m-1)));
}
int main(){
into();
work();
outo();
return 0;
}