1. 程式人生 > >CodeForces 138C Mushroom Gnomes - 2 (線段樹)

CodeForces 138C Mushroom Gnomes - 2 (線段樹)

題意
給你n個蘑菇和m顆大樹的位置,以及大樹往左倒往右倒的概率,大樹的高度,和蘑菇的權值,蘑菇被壓倒必死,問你蘑菇不被壓死的權值的最大的期望是多少?
思路
對於一顆樹而言,他往左倒的概率是 a 那麼不往左倒的概率就是 1

a ,那麼我們線段樹維護一下某個區間不被壓倒(樹不會倒)的概率就好了,具體怎麼維護,我們還是把所有點離散存下來,之後以離散後的點為區間建立線段樹節點原來都是1,之後更新每個區間不被壓倒的概率就好了,最後我們把權值*概率就行了。
ps:線段樹謎之開點,開了尼瑪16倍,,,
程式碼

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 1e5+10; struct Tree { int pos,h; double l,r; }Tree[maxn]; struct Mush { int pos,val; }mush[maxn]; int Hash[maxn<<4]; double tree[maxn<<4]; int n , m; void build(int l,int r,int rt) { tree[rt] = 1; if(l == r) return ; int m = (l+r)>>1; build(lson); build(rson); } void update(int
L,int R,double val,int l,int r,int rt) { if(l>=L && R >= r) { tree[rt] *= val; return ; } int m = (l+r)>>1; if(m >= L) update(L,R,val,lson); if(R > m) update(L,R,val,rson); } double query(int pos,int l,int r,int rt) { if(l == r) return tree[rt]; int m = (l+r)>>1; if(m >= pos) return tree[rt] * query(pos,lson); else return tree[rt] * query(pos,rson); } int main() { scanf("%d%d",&n,&m); int x,y; int cnt = 0; for(int i = 0 ; i < n ; i++) { scanf("%d%d%d%d",&Tree[i].pos,&Tree[i].h,&x,&y); Tree[i].l = x/100.0,Tree[i].r = y/100.0; Hash[cnt++] = Tree[i].pos-1; Hash[cnt++] = Tree[i].pos + Tree[i].h; Hash[cnt++] = Tree[i].pos + 1; Hash[cnt++] = Tree[i].pos - Tree[i].h; } for(int i = 0 ; i < m ; i++) { scanf("%d%d",&mush[i].pos,&mush[i].val); Hash[cnt++] = mush[i].pos; } sort(Hash,Hash+cnt); cnt = unique(Hash,Hash+cnt) - Hash; build(1,cnt,1); for(int i = 0 ; i < n ; i++) { int mid1 = lower_bound(Hash,Hash+cnt,Tree[i].pos-1) - Hash + 1; int mid2 = lower_bound(Hash,Hash+cnt,Tree[i].pos+1) - Hash + 1; int l = lower_bound(Hash,Hash+cnt,Tree[i].pos - Tree[i].h) - Hash + 1; int r = lower_bound(Hash,Hash+cnt,Tree[i].pos + Tree[i].h) - Hash + 1; update(l,mid1,(1.0-Tree[i].l),1,cnt,1); update(mid2,r,(1.0-Tree[i].r),1,cnt,1); } double ans = 0; for(int i = 0 ; i < m ; i++) { int pos = lower_bound(Hash,Hash+cnt,mush[i].pos) - Hash + 1; ans += query(pos,1,cnt,1) * mush[i].val; } printf("%.10f\n",ans); }