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;
}
原文地址:https://www.cnblogs.com/hznumqf/p/15369418.html