zoukankan      html  css  js  c++  java
  • LOJ3160 「NOI2019」斗主地

    LOJ3160 「NOI2019」斗主地

    正解

    想了半天发现自己连第一步都没有想出来……翻翻题解发现人们都不屑于讲这步……

    就是说,洗牌之后,每种可能出现的方案的出现概率是相同的。

    为什么……

    从初始状态开始,一个最终状态的概率是若干步的概率乘起来的。看分母,是(n!);看分子,是(A_i!(n-A_i)!),从而得证,概率为(frac{1}{inom{n}{A_i}})

    当然有个组合意义的说法:因为两堆牌的内部的顺序固定,所以它们之间不存在区别。那么相当于有(n)个球,(A_i)个黑球(n-A_i)个白球,每次随机取出一个。最终形成的排列和原来的模型是一一对应的。

    接下来是个结论:(E_i(x))表示(i)次操作之后(x)位置上值的期望,它可以表示成一个关于(x)的二次多项式的形式。

    知道这个结论之后,从(E_{i-1}(x))推到(E_i(x)),只需要随便取三个值带入(E_i(x))算,算完之后插值就可以得到它的多项式系数了。

    做法讲完了,接下来是证明:

    考虑归纳:

    枚举位置(x)上的球转移到位置(y)的概率,于是有:(inom{n}{A_i} E_i(y)=sum_{x=1}^{A_i}inom{y-1}{x-1}inom{n-y}{A_i-x}E_{i-1}(x)+sum_{x=1}^{n-A_i}inom{y-1}{x-1}inom{n-y}{n-A_i-x}E_{i-1}(A_i+x))

    我们要证这条式子是个只和(y)有关的多项式。下面只考虑求左边,另一边同理:

    由于(E_{i-1}(x))为多项式,所以可以把它拆开成若干项分别算。直接普通的多项式可能不太好算,于是这里取(E_{i-1}(x)=sum_{k=0}^2f_k(x-1)^{underline k})

    于是要证:(sum_{x=1}^{A_i}inom{y-1}{x-1}inom{n-y}{A_i-x}(x-1)^{underline k})是个和(y)有关的多项式。

    [原式=inom{y-1}{k}k!sum_{x=1}^{A_i}inom{y-1-k}{x-1-k}inom{n-y}{A_i-x}=inom{y-1}{k}k!inom{n-k-1}{A_i-k-1} ]

    (此处省略若干步骤,想推的同学慢慢推……)

    看到这条式子和(x)无关,并且显然有关(y)的二次多项式。由此得证。


    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 10000010
    #define M 500010
    #define ll long long
    #define mo 998244353
    ll qpow(ll x, ll y = mo - 2) {
        ll r = 1;
        for (; y; y >>= 1, x = x * x % mo)
            if (y & 1)
                r = r * x % mo;
        return r;
    }
    int n, m, type;
    int fac[N], ifac[N];
    void initC(int n) {
        fac[0] = 1;
        for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % mo;
        ifac[n] = qpow(fac[n]);
        for (int i = n - 1; i >= 0; --i) ifac[i] = (ll)ifac[i + 1] * (i + 1) % mo;
    }
    ll C(int m, int n) { return (ll)fac[m] * ifac[n] % mo * ifac[m - n] % mo; }
    ll f0, f1, f2;
    ll dot(ll x) { return ((f2 * x + f1) % mo * x + f0) % mo; }
    void cha_1n2(ll y1, ll yn, ll y2) {
        static ll z1 = qpow(n - 1), zn = qpow((ll)(n - 1) * (n - 2) % mo), z2 = mo - qpow(n - 2);
        y1 = y1 * z1 % mo;
        yn = yn * zn % mo;
        y2 = y2 * z2 % mo;
        f0 = (y1 * n * 2 + yn * 2 + y2 * n) % mo;
        f1 = (mo - (y1 * (n + 2) + yn * 3 + y2 * (n + 1)) % mo) % mo;
        f2 = (y1 + yn + y2) % mo;
    }
    int main() {
        // freopen("in.txt","r",stdin);
        freopen("landlords.in", "r", stdin);
        freopen("landlords.out", "w", stdout);
        scanf("%d%d%d", &n, &m, &type);
        initC(n);
        f0 = 0, f1 = (type == 1), f2 = (type == 2);
        for (int i = 1; i <= m; ++i) {
            int A;
            ll E1, En, E2;
            scanf("%d", &A);
            E1 = ((1 <= A ? C(n - 1, A - 1) * dot(1) : 0) + (1 <= n - A ? C(n - 1, n - A - 1) * dot(1 + A) : 0)) %
                 mo;
            En = ((1 <= A ? C(n - 1, A - 1) * dot(A) : 0) + (1 <= n - A ? C(n - 1, n - A - 1) * dot(n) : 0)) % mo;
            E2 = ((1 <= A ? C(n - 2, A - 1) * dot(1) : 0) + (1 <= n - A ? C(n - 2, n - A - 1) * dot(1 + A) : 0) +
                  (2 <= A ? C(n - 2, A - 2) * dot(2) : 0) + (2 <= n - A ? C(n - 2, n - A - 2) * dot(2 + A) : 0)) %
                 mo;
            ll invC = (ll)ifac[n] * fac[n - A] % mo * fac[A] % mo;
            cha_1n2(E1 * invC % mo, En * invC % mo, E2 * invC % mo);
        }
        int Q;
        scanf("%d", &Q);
        while (Q--) {
            int x;
            scanf("%d", &x);
            printf("%lld
    ", dot(x));
        }
        return 0;
    }
    
  • 相关阅读:
    java.lang.NoSuchMethodError: org.springframework.beans.factory.annotation.InjectionMetadata.<init>(Ljava/lang/Class;)V
    tomcat下jndi的三种配置方式
    使用@RequestParam绑定请求参数到方法参数
    IE下easyui 缓存问题
    many to one could not resolve property
    aop郁闷错误
    Spring 运用 pointcut 和 advisor 对特定的方法进行切面编程
    放大改进版~
    cocos2d-x嵌入移动MM短代支付IAP2.4的SDK,点击支付崩溃的解决的方法
    在 Android* 商务应用中实施地图和地理围栏特性
  • 原文地址:https://www.cnblogs.com/jz-597/p/13458030.html
Copyright © 2011-2022 走看看