zoukankan      html  css  js  c++  java
  • [题解] [CF886E] Maximum Element

    题解

    题面

    返回错误值的方案数就是总方案数减去返回正确值的方案数

    于是我们就只要求返回正确值的方案数了

    什么时候会返回正确值?

    (n) 未出现的时候均未返回就会返回正确值

    所以我们设 (f[i]) 为长度为 (i) 的序列还没有返回的方案数

    [displaystyle f[i] = sum_{j=i-k+1}^{i}f[j - 1]inom{i-1}{j-1}(i - j)! ]

    意为, 对于最大值 (i) , 我们假设他放在 (j) 位置上, 因为不能返回, 所以 (i) 后面不能有 (k) 个数

    ((i - 1)) 个数中任取 (j - 1) 个数放到前面去摆放, 且不能返回值

    另外的 (i - j) 个数在 (j) 后面可以随便摆, 反正最大值已经确定了

    所以就是上面那个式子

    把他化一下

    [displaystyle egin{aligned}f[i] &= sum_{j=i-k+1}^{i}f[j - 1]frac{(i-1)!}{(j-1)!}\frac{f[i]}{(i-1)!}&=sum_{j=i-k+1}^{i}frac{f[j - 1]}{(j-1)!}end{aligned} ]

    (g[i] = frac{f[i]}{i!})

    所以就变成了

    [displaystyle g[i]=frac{sum_{j=i-k}^{i-1}g[j]}{i} ]

    再看最后的答案如何计算

    [displaystyle ans = n!-sum_{i=1}^{n}f[i - 1]inom{n-1}{i-1}(n-i)! ]

    右边那个 (sum) 分析方式同上

    拆一下有

    [displaystyle egin{aligned}ans &=n! - sum_{i=1}^{n}f[i - 1]frac{(n-1)!}{(i-1)!}\&=n!-sum_{i=1}^n(n-1)!frac{f[i - 1]}{(i-1)!}\&=n!-sum_{i=1}^n(n-1)!g[i-1]\&=(n-1)!(n-sum_{i=0}^{n-1}g[i])end{aligned} ]

    递推出 (g) 即可

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    const int N = 1000005;
    const int mod = 1000000007; 
    using namespace std;
    
    int n, k, inv[N], ans, sum[N]; 
    
    template < typename T >
    inline T read()
    {
    	T x = 0, w = 1; char c = getchar();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * w; 
    }
    
    int main()
    {
    	n = read <int> (), k = read <int> ();
    	if(n <= k + 1) { puts("0"); return 0; }
    	sum[0] = 1; 
    	for(int i = (ans = 1); i <= n; i++)
    	{
    		if(i == 1) inv[i] = 1;
    		else inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod; 
    		ans = 1ll * ans * i % mod;
    		sum[i] = (sum[i - 1] + 1ll * (sum[i - 1] - (i - k - 1 >= 0 ? sum[i - k - 1] : 0) + mod) % mod * inv[i] % mod) % mod; 
    	}
    	ans = (ans - 1ll * sum[n - 1] * ans % mod * inv[n] % mod + mod) % mod;
    	printf("%d
    ", ans); 
    	return 0; 
    }
    
  • 相关阅读:
    linux 命令——19 find (转)
    linux 命令——18 locate (转)
    linux 命令——17 whereis(转)
    linux 命令——16 which(转)
    linux 命令——15 tail (转)
    linux 命令——14 head (转)
    Java for LeetCode 038 Count and Say
    Java for LeetCode 037 Sudoku Solver
    Java for LeetCode 036 Valid Sudoku
    Java for LeetCode 035 Search Insert Position
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12208290.html
Copyright © 2011-2022 走看看