码迷,mamicode.com
首页 > 其他好文 > 详细

CF886E Maximum Element

时间:2019-03-06 15:09:05      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:maximum   can   class   codeforce   math   存在   namespace   .com   pre   

link

题目大意:Petya写了一个假的序列求max

int fast_max(int n, int a[]) {
    int ans = 0;
    int offset = 0;
    for (int i = 0; i < n; ++i)
        if (ans < a[i]) {
            ans = a[i];
            offset = 0;
        } else {
            offset = offset + 1;
            if (offset == k)
            return ans;
        }
    return ans;
}

现在请问对于n的所有排列和代码中的k,调用这个函数返回的不是n的方案数

题解:根据代码 如果序列中出现一个位置的后面连续k个数比这个数小那么就返回这个数

这是一个或的关系,我们容斥一下,方案数为n!-合法方案数,显然合法方案数为序列中n的前面不存在

一个位置的后面连续k个数比这个数小那么就返回这个数

那么我们设\(f_i?\)为i的排列不存在某个位置的后面连续k个数比这个数小的情况

我们考虑枚举最大值\(i\)摆放位置,由于这个值也不能满足条件,所以这个数后面最多有k-1个数,显然我们有dp方程\(f_i=\sum_{j=i-k+1}^{i}f_{j-1}{(i-1)}^{\underline{i-j}}\),不过这个方程是O(nk)的,我们可以把排列数拆一下,写成\(f_i=(i-1)!\sum_{j=i-k+1}^i\frac{f_{j-1}}{(j-1)!}\),我们发现把\(\frac{f_i}{i!}\)搞个前缀和就能做到O(n)?转移了。

然后我们考虑收集答案,我们还是考虑枚举\(n\)摆放位置,就有\(Ans=\sum_{i=1}^nf_{i-1}(n-1)^{\underline{n-i}}\),然后我们发现收集答案就是O(n)的就可以瞎几把写了。

难点主要是设状态。。。

code:

#include <cstdio>
using namespace std;

const int xkj = 1000000007;
int n, k, fac[1000010], inv[1000010], f[1000010], s[1000010];

int qpow(int x, int y)
{
    int res = 1;
    for (x %= xkj; y > 0; y >>= 1, x = x * (long long)x % xkj)
        if (y & 1) res = res * (long long)x % xkj;
    return res;
}

int main()
{
    scanf("%d%d", &n, &k);
    fac[0] = 1;
    for (int i = 1; i <= n; i++) fac[i] = fac[i - 1] * (long long)i % xkj;
    inv[n] = qpow(fac[n], xkj - 2);
    for (int i = n; i >= 1; i--) inv[i - 1] = inv[i] * (long long)i % xkj;
    f[0] = s[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        f[i] = fac[i - 1] * (long long)(s[i - 1] - (i > k ? s[i - k - 1] : 0) + xkj) % xkj;
        s[i] = (f[i] * (long long)inv[i] + s[i - 1]) % xkj;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ans = (ans + f[i - 1] * (long long)fac[n - 1] % xkj * inv[i - 1] % xkj) % xkj;
    }
    printf("%d\n", (fac[n] - ans + xkj) % xkj);
    return 0;
}

CF886E Maximum Element

标签:maximum   can   class   codeforce   math   存在   namespace   .com   pre   

原文地址:https://www.cnblogs.com/oier/p/10483117.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!