zoukankan      html  css  js  c++  java
  • 期望+DP ZOJ 3929 Deque and Balls

    题目链接

    题意:给你n个数,按照顺序依次放入一个双端队列(可放在头部,也可以放在尾部),求xi > xi+1的期望 * 2^n mod (1e9 +7)

    分析:期望*2^n=出现这种排法的概率*这种排法的desents数*2^n = 1/(2^(n-1)) * 2^n * 每一种排法每一个数的desents数=2* 每一种排法每一个数字的贡献值.

    首先插入xi有两种方法,相当于有两种排法,那么求前缀时ans[i] = ans[i-1] * 2,然后再考虑当前xi的贡献值:如果放在头部,那么要求出满足xi>xj的xj的出现次数和,然后发现第一个数字出现1次,第二个2次,第三个4次,8,16...放在尾部同理,用树状数组累计次数和,至于i之后的数字如何排都不会对当前i做贡献,所以*.

    #include <bits/stdc++.h>
    
    const int N = 1e5 + 5;
    const int MOD = 1e9 + 7;
    
    template<class T>
    void add(T &a, T b) {
        a += b;
        if (a >= MOD) {
            a -= MOD;
        }
    }
    
    struct BIT {
        int c[N];
        int n;
        void init(int n) {
            this->n = n;
            std::fill (c, c+1+n, 0);
        }
        void updata(int p, int v) {
            for (int i=p; i<=n; i+=i&-i) {
                add (c[i], v);
            }
        }
        int query(int p) {
            int ret = 0;
            for (int i=p; i>0; i-=i&-i) {
                add (ret, c[i]);
            }
            return ret;
        }
    };
    BIT L, R;
    
    int a[N], cnt[N];
    
    int pow_mod(int x, int n) {
        int ret = 1;
        while (n) {
            if (n & 1) {
                ret = 1ll * ret * x % MOD;
            }
            x = 1ll * x * x % MOD; n >>= 1;
        }
        return ret;
    }
    
    void pre_init() {
        cnt[1] = cnt[2] = 1;
        for (int i=3; i<=100000; ++i) {
            cnt[i] = 1ll * cnt[i-1] * 2 % MOD;
        }
    }
    
    int main() {
        pre_init ();
        int T; scanf ("%d", &T);
        while (T--) {
            int n; scanf ("%d", &n);
            int nn = n + 3;
            L.init (nn); R.init (nn);
            for (int i=1; i<=n; ++i) {
                scanf ("%d", a+i);
            }
            long long ans = 0;
            for (int i=1; i<=n; ++i) {
                long long tmp = 0LL + L.query (a[i] - 1) + R.query (nn-a[i]-1);
                tmp = tmp * pow_mod (2, n - i) % MOD;
                add (ans, tmp);
                L.updata (a[i], cnt[i]);
                R.updata (nn - a[i], cnt[i]);
            }
            ans = ans * 2 % MOD;
            std::cout << ans << '
    ';
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5387417.html
Copyright © 2011-2022 走看看