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;
    }
    

      

  • 相关阅读:
    You Don't Know JS: Async & Performance(第2章,Callbacks)
    You Don't Know JS: this & Object Prototypes (第6章 Behavior Delegation)附加的ES6 class未读
    C#抓取网页内容
    输出jq对象
    ASP.NET MVC 常用内置验证特性
    MVC不错的学习资料
    让Entity Framework启动不再效验__MigrationHistory表
    多线程
    递归
    序列化
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5387417.html
Copyright © 2011-2022 走看看