列表

详情


NC52280. 计数

描述

sun最近对计数问题来了兴趣,现在他有一个问题想问问你:

 

有一个含有n个数字的序列,每个数的大小是不超过1000的正整数,同时这个序列是个单调不增序列。但是很不幸的是,序列在保存过程中有些数字丢失了,请你根据上述条件,计算出有多少种不同的序列满足上述条件,答案对1000000007取模。(具体可以看样例)

输入描述

第一行包含一个整数n,表示这个序列的长度。
第二行为n个整数a_i,用空格隔开,如果数字是0,代表这个数字丢失了,其他的数字都在1~1000之间

输出描述

输出一行,表示答案。

示例1

输入:

3
9 0 8

输出:

2

示例2

输入:

2
5 4

输出:

1

示例3

输入:

3
0 0 0

输出:

167167000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 139ms, 内存消耗: 16012K, 提交时间: 2019-09-16 21:08:25

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7,maxn=1e6+1;
typedef long long ll;
ll f[maxn],a[maxn];
ll quick(ll a,ll b)
{
    ll r=1;
    for(;b;b>>=1,a=a*a%mod)
    if(b&1) r=r*a%mod;
    return r;
}
void init()
{
    f[0]=1;
    for(int i=1;i<maxn;++i)
    f[i]=(f[i-1]*i)%mod;
}
ll c(ll a,ll b)
{
    return f[a]*quick(f[b],mod-2)%mod*quick(f[a-b],mod-2)%mod;
}
int main()
{
    int n;
    scanf("%d",&n);
    init();
    for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
    ll ans=1,cnt=0,pre=1000;a[n+1]=1;
    for(int i=1;i<=n+1;++i)
    {
        if(a[i]==0) cnt++;
        else{
            ll size=pre-a[i]+1;
            ans=ans*(c(size+cnt-1,cnt)%mod)%mod;
            cnt=0;
            pre=a[i];
        }
    }
    printf("%lld\n",ans);
}

C++(g++ 7.5.0) 解法, 执行用时: 199ms, 内存消耗: 15964K, 提交时间: 2022-11-09 21:10:21

#include<stdio.h>
#define ll long long
const ll p=1e9+7;
const ll N=1e6+7;
ll inv[N],a[N];
ll c(int n,int m)
{
	if(n<m) return 0;
    ll ans=1;
    for(ll i=1;i<=m;i++)
    ans=ans*((n-i+1)%p)%p*inv[i]%p;
    return ans;
}
int main()
{
    ll ans=1,last=1000,z,n; /*z为一段连续空的前段点,last为一段连续空的第一个数的大小*/
    scanf("%lld",&n);
    inv[1]=1;
    for(ll i=2;i<N;i++)
    inv[i]=inv[p%i]*(p-p/i)%p;
    for(ll i=1;i<=n;i++)
    {
       scanf("%lld",&a[i]);
       if(a[i])
       {
          (ans*=c(last-a[i]+i-z-1,i-z-1))%=p;
          last=a[i];
          z=i; 
       }
    }
    (ans*=c(last-1+n-z,n-z))%=p;
    printf("%lld\n",ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 196ms, 内存消耗: 23908K, 提交时间: 2019-09-13 20:11:03

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long 
using namespace std;
const ll XJQ=1e9+7,N=2e6+100;
ll num[N],n,ans=1,last=1000,z,inv[N];
ll C(ll n,ll m)
{
	if(n<m) return 0;
	ll ans=1;
	for(ll i=1;i<=m;i++)
		ans=ans*((n-i+1)%XJQ)%XJQ*inv[i]%XJQ;
	return ans;
}
int main()
{
	scanf("%lld",&n);
	inv[1]=1;
	for(ll i=2;i<=N;i++)
		inv[i]=inv[XJQ%i]*(XJQ-XJQ/i)%XJQ;
	for(ll i=1;i<=n;i++){
		scanf("%lld",&num[i]);
		if(num[i]){
			(ans*=C(last-num[i]+i-z-1,i-z-1))%=XJQ;
			last=num[i];z=i;
		}
	}
	(ans*=C(last-1+n-z,n-z))%=XJQ;
	printf("%lld",ans);
}

上一题