zoukankan      html  css  js  c++  java
  • NowCoder2018多校F Take 期望 转化

    NowCoder2018多校F Take 期望 转化

    题意

    给出(n)个物品,对于第(i)个物品,有(p_i)的概率打开这个物品,若该物品的权值(d[i])比当前获得的物品的最大值大,就更新这个最大值

    求更新的期望次数

    [1leq n leq 100000\ 1 leq p_i leq 100\ 1leq d_i leq 1e9 ]

    分析

    直接做显然是一个复杂度较高的二维DP

    考虑计算每个物品对总更新次数的贡献,每个物品能够被作为最大值更新显然和后面的东西没有关系,前面的物品权值小于等于它的和它也没更新(打不打开都是1),因此只需要管前(i - 1)个物品中权值大于(d_i)的物品

    [E= P = p_i prod_{j <i and d_j > d_i} (1-p_j) ]

    显然树状数组扫一遍或者线段树维护后缀积即可

    代码

    const int maxn = 1e5 + 5;
     
    inline int get(VI &a,int val){
        return lower_bound(all(a),val) - a.begin();
    }
     
    struct BIT{
        int c[maxn<<2];
        void init() {
          fill(c,c+(maxn<<2),1);
        }
        void add(int p, int x, int l, int r, int i) {
          if (p == l && p == r) {
            c[i] = mul(c[i], x);
            return;
          }
          int mid = l + r >> 1;
          if (p <= mid) add(p, x, l, mid, i << 1);
          else add(p, x, mid + 1, r, i << 1 | 1);
          c[i] = mul(c[i << 1], c[i << 1 | 1]);
        }
        void ADD(int pos,int x){
            add(pos, x, 1, maxn, 1);
        }
        int qr(int l, int r, int L, int R, int i) {
          if (l <= L && r >= R) {
            return c[i];
          }
          int mid = L + R >> 1;
          int res = 1;
          if (l <= mid) res = mul(res, qr(l, r, L, mid, i << 1));
          if (r > mid) res = mul(res, qr(l, r, mid + 1, R, i << 1 | 1));
          return res;
        }
        int query(int pos){
            return qr(pos, maxn, 1, maxn, 1);
        }
    }bit;
     
     
    int main(){
        int iv = ksm(100);
        int n = rd();
        int MUL = 1;
        VI p(n + 1),d(n + 1);
        for(int i = 1;i <= n;i++)
            p[i] = rd(),d[i] = rd();
        int ans = 0;
        auto a = d;
        sort(all(a));
        a.erase(unique(all(a)),a.end());
        int len = (int)a.size();
        bit.init();
    //    for(int i = 1;i <= len;i++)
    //        bit.c[i] = 1;
        for(int i = 1;i <= n;i++){
            int tmp = mul(p[i],iv);
            int val = get(a,d[i]);
            //tmp = mul(tmp,mul(MUL,ksm(bit.query(val))));
            tmp = mul(tmp, bit.query(val + 1));
            add(ans,tmp);
    //        int v = mul(bit.query(val),ksm(bit.query(val - 1)));
    //        bit.ADD(val,ksm(v));
    //        bit.ADD(val,mul(100 - p[i],iv));
    //        MUL = mul(MUL,mul(100 - p[i],iv));
            bit.ADD(val, mul(100-p[i], iv));
        }
        cout << ans;
    }
    
  • 相关阅读:
    一条查询SQl是怎样执行的
    MySQL45讲笔记-事务隔离级别,为什么你改了数据我看不见
    了解一下IO控制器与控制方式
    进程的同步与互斥
    预防死锁,检测死锁,避免死锁,解除死锁....
    初识Git
    剑指offer-查找数组中重复的数字
    常见的几种进程调度算法
    操作系统-进程的状态以及转换
    中断、异常、系统调用
  • 原文地址:https://www.cnblogs.com/hznumqf/p/15369418.html
Copyright © 2011-2022 走看看