zoukankan      html  css  js  c++  java
  • CF1153F Serval and Bonus Problem

    CF1153F Serval and Bonus Problem

    官方的解法是(O(n ^ 2))的,这里给出一个(O(n log n))的做法。

    首先对于长度为(l)的线段,显然它的答案就是长度为(1)的线段的答案( imes l),这样做只是为了方便计算。

    考虑对于数轴上区间([0,1])内任意一个点(x),它被一条随机线段覆盖的概率是多少:线段的两个端点都在它左边的概率是(x ^ 2)、都在它右边的概率是((1 - x) ^ 2),那么它被覆盖的概率即为(p(x) = 1 - x^2 - (1 - x) ^ 2 = 2 x (1 - x))

    那么他被(ge k)条线段覆盖的概率为(f(x) = sum limits _{i = k} ^ n inom{n}{i} p(x) ^ i (1 - p(x)) ^ {n - i})

    根据定积分的定义就得到区间([0,1])内被(ge k)条线段覆盖的长度期望为(int _{0} ^{1} f(x) mathrm{d} x)

    现在我们的问题就是怎么算这个东西了:

    [egin{align*} int _ 0 ^ 1 f(x) mathrm{d} x & = int _ 0 ^ 1 sum limits _{i = k} ^ n inom {n} {i} (2x (1 - x)) ^ i (1 - 2x (1 - x)) ^ {n - i} mathrm{d} x \ & = sum limits _{i = k} ^ n inom {n} {i} int _ 0 ^ 1 (2x (1 - x)) ^ i sum limits _{j = 0} ^ {n - i} inom {n - i} {j} (-2x(1 - x)) ^ j mathrm{d} x \ & = sum limits _{i = k} ^n inom {n} {i} sum limits _{j = 0} ^ {n - i} inom {n - i} {j} (-1) ^ j 2 ^ {(i + j)} int _ 0 ^ 1 x ^ {i + j} (1 - x) ^ {i + j} mathrm{d} x end{align*} ]

    推到这里,就可以把积分去掉了,这是一个Beta Function的形式:记结论吧

    [B(x, y) = int _ 0 ^ 1 t ^ {x - 1} (1 - t) ^ {y - 1} mathrm{d} t = frac {(x - 1) ! (y - 1) !} {(x + y - 1) !} ]

    代入得:

    [egin{align*} int _ 0 ^ 1 f(x) mathrm{d} x & = sum limits _{i = k} ^n inom {n} {i} sum limits _{j = 0} ^ {n - i} inom {n - i} {j} (-1) ^ j 2 ^ {(i + j)} frac {((i + j) ! ) ^ 2} {(2(i + j) + 1) !} \ & = n ! sum limits _{i = k} ^ n sum limits _ {j = 0} ^ {n - i} frac {1} {i !} frac {(-1) ^ j} {j !} frac {2 ^ {i + j} ((i + j) !) ^ 2} {(2(i+ j) + 1) ! (n - (i + j)) !} end{align*} ]

    (t = i + j)(f[i] = frac {1} {i})(g[j] = frac {(-1) ^ j} {j !})(h[t] = frac{2^t (t !) ^ 2} {(2 t + 1) ! (n - t) !}),考虑枚举(t)

    [egin{align*} int _ 0 ^ 1 f(x) mathrm{d} x & = n ! sum limits _{t = k} ^ n h[t] sum limits _ {i = k} ^ t f[i] g[t - i] end{align*} ]

    这后面就是一个非常显然的卷积式子了,直接FFT即可。

    答案记得( imes l)

    //written by newbiechd
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define BUF 1000000
    using namespace std;
    const int N = 100003, yyb = 998244353, Gg = 3, Gi = 332748118;
    char buf[BUF], *p1, *p2;
    inline char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, BUF, stdin), p1 == p2) ? EOF : *p1++; }
    inline int rd() {
        register int f = 0;
        register char c;
        while (!isdigit(c = gc())) {}
        do
            f = f * 10 + (c ^ 48);
        while (isdigit(c = gc()));
        return f;
    }
    int rev[N], G[2][N];
    inline int power(int x, int y) {
        register int o = 1;
        for (; y; y >>= 1, x = 1ll * x * x % yyb)
            if (y & 1)
                o = 1ll * o * x % yyb;
        return o;
    }
    inline void ntt(int *f, int len, int opt) {
        register int i, j, k, x, y, p, q;
        for (i = 1; i < len; ++i)
            if (i < rev[i])
                swap(f[i], f[rev[i]]);
        for (i = 1; i < len; i <<= 1) {
            p = G[opt][i];
            for (j = 0; j < len; j += i << 1)
                for (k = 0, q = 1; k < i; ++k, q = 1ll * p * q % yyb)
                    x = f[j | k], y = 1ll * q * f[i | j | k] % yyb, f[j | k] = (x + y) % yyb, f[i | j | k] = (x - y) % yyb;
        }
    }
    int fac[N], invFac[N], f[N], g[N], h[N];
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("a.in", "r", stdin);
        freopen("a.out", "w", stdout);
    #endif
        int n = rd(), m = n << 1 | 1, k = rd(), l = rd(), i, len, tmp, ans = 0;
        fac[0] = 1;
        for (i = 1; i <= m; ++i)
            fac[i] = 1ll * fac[i - 1] * i % yyb;
        invFac[m] = power(fac[m], yyb - 2);
        for (i = m; i; --i)
            invFac[i - 1] = 1ll * invFac[i] * i % yyb;
        for (i = k; i <= n; ++i)
            f[i] = invFac[i];
        for (i = 0; i <= n; ++i)
            g[i] = i & 1 ? yyb - invFac[i] : invFac[i];
        for (len = 1; len <= m; len <<= 1) {}
        for (i = 1; i < len; ++i)
            rev[i] = (rev[i >> 1] >> 1) | (i & 1 ? len >> 1 : 0);
        for (i = 1; i < len; i <<= 1)
            G[0][i] = power(Gg, (yyb - 1) / (i << 1)), G[1][i] = power(Gi, (yyb - 1) / (i << 1));
        ntt(f, len, 0), ntt(g, len, 0);
        for (i = 0; i < len; ++i)
            f[i] = 1ll * f[i] * g[i] % yyb;
        ntt(f, len, 1), tmp = power(len, yyb - 2);
        for (i = 1; i <= n; ++i)
            f[i] = 1ll * f[i] * tmp % yyb;
        for (i = 1, tmp = 2; i <= n; tmp = (tmp << 1) % yyb, ++i)
            h[i] = 1ll * fac[i] * fac[i] % yyb * tmp % yyb * invFac[i << 1 | 1] % yyb * invFac[n - i] % yyb;
        for (i = k; i <= n; ++i)
            ans = (1ll * f[i] * h[i] % yyb + ans) % yyb;
        ans = 1ll * ans * fac[n] % yyb * l % yyb, printf("%d
    ", (ans + yyb) % yyb);
        return 0;
    }
    
    
  • 相关阅读:
    智能推荐算法演变及学习笔记(三):CTR预估模型综述
    从中国农业银行“雅典娜杯”数据挖掘大赛看金融行业数据分析与建模方法
    智能推荐算法演变及学习笔记(二):基于图模型的智能推荐(含知识图谱/图神经网络)
    (设计模式专题3)模板方法模式
    (设计模式专题2)策略模式
    (设计模式专题1)为什么要使用设计模式?
    关于macOS上常用操作命令(持续更新)
    记录下关于RabbitMQ常用知识点(持续更新)
    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
    SpringCloud教程二:Ribbon(Finchley版)
  • 原文地址:https://www.cnblogs.com/cj-chd/p/10715436.html
Copyright © 2011-2022 走看看