链接:https://ac.nowcoder.com/acm/contest/1085/J
来源:牛客网
计数
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld题目描述
小sun最近对计数问题来了兴趣,现在他有一个问题想问问你:
有一个含有n个数字的序列,每个数的大小是不超过1000的正整数,同时这个序列是个单调不增序列。但是很不幸的是,序列在保存过程中有些数字丢失了,请你根据上述条件,计算出有多少种不同的序列满足上述条件,答案对1000000007取模。(具体可以看样例)
输入描述:
第一行包含一个整数n,表示这个序列的长度。
第二行为n个整数aia_iai,用空格隔开,如果数字是0,代表这个数字丢失了,其他的数字都在1~1000之间
输出描述:
输出一行,表示答案。示例1
输入
3 9 0 8输出
2示例2
输入
2 5 4输出
1示例3
输入
3 0 0 0输出
167167000备注:
1≤n≤1e61\leq n \leq 1e61≤n≤1e6 0≤ai≤10000\leq a_i \leq 10000≤ai≤1000
#include<bits/stdc++.h> #define ll long long #define mod 1000000007 using namespace std; int t; int a[1000006]; ll A[1000006],inv[1000006]; ll quick_mi(ll x,ll y)//快速幂求逆元 inv { ll res=1; while(y) { if(y&1) res=res*x%mod;//!!!res取模啊!!! x*=x; x%=mod; y>>=1; } return res; } ll C(ll n,ll m)//组合数 { ll ans=A[n]*inv[m] % mod*inv[n-m] % mod; return ans; } int main() { cin>>t; for(int i=0;i<t;i++) { scanf("%d",&a[i]); } A[0]=1; //!!! inv[0]=1;//!!! 特殊处理 for(int i=1;i<=1000000;i++)//阶乘预处理范围 { A[i]=A[i-1]*i%mod;//排列数 阶乘 inv[i]=quick_mi(A[i],mod-2); } ll ans=1; int num=0; int last=1000; for(int i=0;i<t;i++) { if(a[i]) { ans=ans*C(last-a[i]+num,num)%mod; last=a[i]; num=0; } else num++; } ans=ans*C(last-1+num,num)%mod; printf("%lld\n",ans); }