Mushroom Gnomes

传送门

题目大意:一条水平直线上有树和蘑菇,已知每颗树的坐标,高度和向左,向右倾倒的概率,已知蘑菇的坐标和该蘑菇的价值,求蘑菇价值总和的期望值。

思路:可以知道一颗树的倾倒可以看做一个区间的概率更新,我们可以离散化蘑菇的坐标点,然后区间更新该区间所有蘑菇的概率,然后遍历所有蘑菇的期望值。

这里我们可以发现,我们不需要用到区间更新的lazy标记,严格来说不需要用到lazy标记的下压操作,因为我们是单点求值,一路找点时,直接概率相乘就行。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <vector>
  6 #include <set>
  7 #include <queue>
  8 
  9 using namespace std;
 10 
 11 #define ll long long
 12 #define pb push_back
 13 #define fi first
 14 #define se second
 15 #define lson(rt) (rt << 1)
 16 #define rson(rt) (rt << 1 | 1)
 17 
 18 const int N = 1e5 + 10;
 19 struct node
 20 {
 21     int rt, l, r;
 22     double p;
 23     int mid() { return (l + r) >> 1; }
 24     inline void init(int l1, int r1) { l = l1; r = r1; p = 1; }
 25 }tree[N << 2];
 26 int b[N], v[N];
 27 
 28 void Build(int rt, int l, int r)
 29 {
 30     tree[rt].init(l, r);
 31     if(l == r) return ;
 32     Build(lson(rt), l, tree[rt].mid());
 33     Build(rson(rt), tree[rt].mid() + 1, r);
 34 }
 35 
 36 void Update(int rt, int l, int r, int lrank, int rrank, double p)
 37 {
 38     if(lrank <= l && r <= rrank) {
 39         //printf("l = %d r = %d
", l, r);
 40         //printf("before rate = %.10f
", tree[rt].p);
 41         tree[rt].p *= p;
 42         //printf("after rate = %.10f
", tree[rt].p);
 43         return ;
 44     }
 45 
 46     if(tree[rt].mid() >= rrank) Update(lson(rt), l, tree[rt].mid(), lrank, rrank, p);
 47     else if(tree[rt].mid() < lrank) Update(rson(rt), tree[rt].mid() + 1, r, lrank, rrank, p);
 48     else {
 49         Update(lson(rt), l, tree[rt].mid(), lrank, rrank, p);
 50         Update(rson(rt), tree[rt].mid() + 1, r, lrank, rrank, p);
 51     }
 52 
 53 }
 54 
 55 double Query(int rt, int l, int r, int rank)
 56 {
 57     if(l == r) return tree[rt].p;
 58 
 59     if(tree[rt].mid() >= rank) return tree[rt].p * Query(lson(rt), l, tree[rt].mid(), rank);
 60     else return tree[rt].p * Query(rson(rt), tree[rt].mid() + 1, r, rank);
 61 }
 62 
 63 void solve()
 64 {
 65     int n, m;
 66     while(~scanf("%d%d", &n, &m)) {
 67 
 68         vector<pair<int, int > > ld, rd;
 69         vector<int > lp, rp;
 70         for(int i = 1; i <= n; ++i) {
 71             int a, h, l, r;
 72             scanf("%d%d%d%d", &a, &h, &l, &r);
 73             ld.pb(make_pair(a - h, a - 1));
 74             rd.pb(make_pair(a + 1, a + h));
 75             lp.pb(l);
 76             rp.pb(r);
 77         }
 78 
 79         vector<int > rank;
 80         for(int i = 1; i <= m; ++i) {
 81             scanf("%d%d", b + i, v + i);
 82             rank.pb(b[i]);
 83         }
 84 
 85         sort(rank.begin(), rank.end());
 86         rank.erase(unique(rank.begin(), rank.end()), rank.end());
 87         //for(auto x : rank) cout << x << " ";
 88         //cout << endl;
 89         int len = rank.size();
 90         Build(1, 1, m);
 91         //cout << "86 lines" << endl;
 92         for(int i = 0; i < n; ++i) {
 93             //cout << "i  =  " << i << endl;
 94             int lrank = lower_bound(rank.begin(), rank.end(), ld[i].fi) - rank.begin() + 1;
 95             int rrank = upper_bound(rank.begin(), rank.end(), ld[i].se) - rank.begin();// + 1;
 96             double p1 = 1.0 - lp[i] / 100.0;
 97            // printf("lr = %d  rr = %d l = %d  r = %d  p = %.10f
", ld[i].fi, ld[i].se, lrank, rrank, p1);
 98             if(lrank <= rrank) Update(1, 1, len, lrank, rrank, p1);
 99             //cout << "93 lines" << endl;
100             lrank = lower_bound(rank.begin(), rank.end(), rd[i].fi) - rank.begin() + 1;
101             rrank = upper_bound(rank.begin(), rank.end(), rd[i].se) - rank.begin();// + 1;
102             p1 = 1.0 - rp[i] / 100.0;
103             //printf("lr = %d  rr = %d l = %d  r = %d  p = %.10f
", rd[i].fi, rd[i].se, lrank, rrank, p1);
104             if(lrank <= rrank) Update(1, 1, len, lrank, rrank, p1);
105             //cout << "98 lines" << endl;
106         }
107 
108        // cout << "100 lines" << endl;
109         double excp = 0;
110         for(int i = 1; i <= m; ++i) {
111             int rankme = lower_bound(rank.begin(), rank.end(), b[i]) - rank.begin() + 1;
112           //  printf("rank_me = %d
", rankme);
113            // printf("rate = %.10f
", Query(1, 1, m, rankme) );
114             excp += Query(1, 1, m, rankme) * (double)v[i];
115         }
116         //printf("rate_root = %.10f
", tree[1].p);
117         //printf("excp = %.10f
", excp);
118         printf("%.10f
", excp);
119     }
120 }
121 
122 int main(){
123 
124     solve();
125 
126     return 0;
127 }
128 
129 /*
130 3 3
131 2 2 50 50
132 4 2 50 50
133 7 7 50 50
134 3 1
135 5 1
136 6 1
137 
138 */
原文地址:https://www.cnblogs.com/SSummerZzz/p/13971104.html