• 【牛客小白月赛17】J


    题目大意:

    题目链接:https://ac.nowcoder.com/acm/contest/1085/J
    有一个含有nn个数字的序列,每个数的大小是不超过10001000的正整数,同时这个序列是个单调不增序列。但是很不幸的是,序列在保存过程中有些数字丢失了,请你根据上述条件,计算出有多少种不同的序列满足上述条件,答案对10000000071000000007取模。(具体可以看样例)


    思路:

    首先题目要求一个单调不增序列,套路性的把位置ii上的数字加上ni+1n-i+1。这样就转变成了一个单调递减序列。
    那么对于位置i,ji,j的两个已知数字,如果(i,j)(i,j)中全部是未知数字,那么显然我们就需要在¥a[i],a[i+1]...a[j1],a[j]a[i],a[i+1]...a[j-1],a[j]a[i]a[j]1a[i]-a[j]-1个数字中选出ji1j-i-1个数字,满足这些数字排序后单调递减。
    显然这就是Ca[i]a[j]1ji1C_{a[i]-a[j]-1}^{j-i-1}。因为组合是满足互不相同的。
    为了方便,就在aa中加入n,0n,0两个元素,注意nn00都是要加上ni+1n-i+1的。


    代码:

    #include <cstdio>
    using namespace std;
    typedef long long ll;
    
    const int N=1000010,MOD=1000000007;
    ll a[N],last,f[N*2],ans;
    int n;
    
    ll power(ll x,ll k)
    {
    	ll s=1;
    	for (;k;k>>=1,x=x*x%MOD)
    		if (k&1) s=s*x%MOD;
    	return s;
    }
    
    ll C(ll x,ll y)
    {
    	if (x<y) return 0;
    	ll inv=power(f[y]*f[x-y]%MOD,MOD-2);
    	return f[x]*inv%MOD;
    }
    
    int main()
    {
    	f[0]=1;
    	for (int i=1;i<=N+2000;i++)
    		f[i]=f[i-1]*i%MOD;
    	scanf("%d",&n); n+=2;
    	a[1]=1000+n;
    	for (int i=2;i<n;i++)
    	{
    		scanf("%d",&a[i]);
    		if (a[i]) a[i]+=(n-i+1);
    	}
    	a[n]=2;
    	ans=1;
    	for (int i=1;i<=n;i++)
    		if (a[i])
    		{
    			if (last) ans=ans*C(a[last]-a[i]-1,i-last-1)%MOD;
    			last=i;
    		}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    求最大公约数伪代码
    XOR加密
    20201225张晓平第五周学习
    pep9课下作业 张晓平
    20201225 张晓平《信息安全专业导论》第四周学习总结
    寻找黑客偶像 20201225张晓平
    《信息安全专业导论》第九周学习总结
    《信息安全专业导论》第八周学习总结
    《信息安全专业导论》第七周学习总结
    《信息安全专业导论》第6周学习总结
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998030.html
Copyright © 2020-2023  润新知