zoukankan      html  css  js  c++  java
  • [PKUWC2018]Minimax [dp,线段树合并]

    好妙的一个题…

    我们设 (f_{i,j})(i) 节点出现 (j) 的概率

    (l = ch[i][0] , r = ch[i][1])
    即左儿子右儿子

    (m) 为叶子结点的个数

    显然,(i) 出现 (j) 的概率为

    [f_{i,j} = f_{l,j} * (p_i sum_{k=1}^{j-1}f_{r,k} + (1-p_i)sum_{k=j+1}^{m}f_{r,k}) + f_{r,j} * (p_i sum_{k=1}^{j-1}f_{l,k} + (1-p_i)sum_{k=j+1}^{m}f_{l,k}) ]

    不难发现,这个柿子有关前缀和和后缀和,可以用线段树合并的操作来进行转移,从下到上转移,求出根节点的概率就好了…

    #include <cstdio>
    #include <algorithm>
    
    int read() {
      int x = 0;
      char c = 0;
      while (c < 48) c = getchar();
      while (c > 47) x = (x << 1) + (x << 3) + (c & 15), c = getchar();
      return x;
    }
    
    const int mod = 998244353;
    int qpow(int x, int y) {
      int ans = 1;
      for (; y; y >>= 1, x = 1ll * x * x % mod)
        if (y & 1) ans = 1ll * ans * x % mod;
      return ans;
    }
    
    int n;
    const int maxn = 3e5 + 10;
    int ch[maxn][2], fa[maxn], cnt[maxn], val[maxn], tmp[maxn], qwq = 0, s[maxn];
    int rt[maxn], ls[maxn << 5], rs[maxn << 5], sum[maxn << 5], mul[maxn << 5];
    int ans = 0, tot = 0;
    
    void pushup(int rt) { sum[rt] = (sum[ls[rt]] +sum[rs[rt]]) % mod; }
    void pushmul(int rt, int v) {
      if (!rt) return;
      sum[rt] = 1ll * sum[rt] * v % mod;
      mul[rt] = 1ll * mul[rt] * v % mod;
    }
    
    void pushd(int rt) {
      if (mul[rt] == 1) return;
      if (ls[rt]) pushmul(ls[rt], mul[rt]);
      if (rs[rt]) pushmul(rs[rt], mul[rt]);
      mul[rt] = 1;
    }
    
    int newnode() {
    	int x = ++ tot; 
    	ls[x] = rs[x] = sum[x] = 0, mul[x] = 1 ;
    	return x ;
    }
    void upd(int& p, int l, int r, int x, int v) {
      if (!p) p = newnode() ;
      if (l == r) {
        sum[p] = v;
        return;
      }
      pushd(p);
      int mid = l + r >> 1;
      (x <= mid) ? upd(ls[p], l, mid, x, v) : upd(rs[p], mid + 1, r, x, v);
      pushup(p);
    }
    
    int merge(int x, int y, int l, int r, int xmul, int ymul, int v) {
      if (!x && !y) return 0;
      if (!x) {
        pushmul(y, ymul);
        return y;
      }
      if (!y) {
        pushmul(x, xmul);
        return x;
      }
      pushd(x), pushd(y);
      int mid = l + r >> 1;
      int lsx = sum[ls[x]], lsy = sum[ls[y]], rsx = sum[rs[x]], rsy = sum[rs[y]];
      ls[x] = merge(ls[x], ls[y], l, mid, (xmul + 1ll * rsy % mod * (1 - v + mod)) % mod,
                    (ymul + 1ll * rsx % mod * (1 - v + mod)) % mod, v);
      rs[x] = merge(rs[x], rs[y], mid + 1, r, (xmul + 1ll * lsy % mod * v) % mod,
                    (ymul + 1ll * lsx % mod * v) % mod, v);
      pushup(x);
      return x;
    }
    
    void out(int x, int l, int r) {
      if (!x) return;
      if (l == r) {
        s[l] = sum[x];
        return;
      }
      int mid = l + r >> 1;
      pushd(x);
      out(ls[x], l, mid);
      out(rs[x], mid + 1, r);
    }
    
    void dfs(int u) {
      if (!cnt[u]) upd(rt[u], 1, qwq, val[u], 1);
      if (cnt[u] == 1) dfs(ch[u][0]), rt[u] = rt[ch[u][0]] ;
      if (cnt[u] == 2) dfs(ch[u][0]), dfs(ch[u][1]), rt[u] = merge(rt[ch[u][0]], rt[ch[u][1]] ,1 , qwq , 0 , 0 , val[u]);
    }
    
    int main() {
      n = read();
      for (int i = 1; i <= n; i++) fa[i] = read();
      for (int i = 1; i <= n; i++)
        if (fa[i]) ch[fa[i]][cnt[fa[i]]++] = i;
      for (int i = 1; i <= n; i++) val[i] = read();
      for (int i = 1; i <= n; i++) {
        if (cnt[i]) {
          val[i] = 1ll * val[i] * qpow(10000, mod - 2) % mod;
        } else {
          tmp[++qwq] = val[i];
        }
      }
      std ::sort(tmp + 1, tmp + qwq + 1);
      for (int i = 1; i <= n; i++)
        if (!cnt[i]) val[i] = std ::lower_bound(tmp + 1, tmp + qwq + 1, val[i]) - tmp;
      dfs(1);
      out(rt[1], 1, qwq);
      for (int i = 1; i <= qwq; i++) ans = (ans + 1ll * i * tmp[i] % mod * s[i] % mod * s[i]) % mod;
      printf("%d
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    CodeForces 219D Choosing Capital for Treeland (树形DP)
    POJ 3162 Walking Race (树的直径,单调队列)
    POJ 2152 Fire (树形DP,经典)
    POJ 1741 Tree (树的分治,树的重心)
    POJ 1655 Balancing Act (树的重心,常规)
    HDU 2196 Computer (树形DP)
    HDU 1520 Anniversary party (树形DP,入门)
    寒门子弟
    JQuery选择器(转)
    (四)Web应用开发---系统架构图
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12321856.html
Copyright © 2011-2022 走看看