HDU-Wind 离散化+线段树
题意为给定了N棵树,M个蘑菇,一阵风刮来,求期望的幸存的蘑菇的权值。
我们可以转化为求每一个蘑菇仔这一阵风过后的期望权值,然后再把所有的蘑菇的权值相加即可。所以我们对于每一棵树进行一次更新,在其安全区域进行更新,这个用线段树来解决,然后再询问一次蘑菇所在地方的安全系数就可以了。
代码如下:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> using namespace std; int N, M, H[350000], idx; struct Tree { int x, H, pl, pr; }t[100005]; struct MoGu { int x, fee; }m[10005]; struct Node { int l, r; double pro; }e[2000005]; int bsearch(int l, int r, int val) { int mid; while (l <= r) { mid = (l + r) >> 1; if (H[mid] > val) r = mid - 1; else if (H[mid] < val) l = mid + 1; else return mid; } } void build(int p, int l, int r) { e[p].l = l, e[p].r = r, e[p].pro = 1.0; if (l != r) { int mid = (l + r) >> 1; build(p<<1, l, mid); build(p<<1|1, mid+1, r); } } void push_down(int p) { e[p<<1].pro *= e[p].pro; e[p<<1|1].pro *= e[p].pro; e[p].pro = 1.0; } void modify(int p, int l, int r, double pro) { if (e[p].l == l && e[p].r == r) { e[p].pro *= pro; } else { push_down(p); int mid = (e[p].l + e[p].r) >> 1; if (r <= mid) modify(p<<1, l, r, pro); else if (l > mid) modify(p<<1|1, l, r, pro); else { modify(p<<1, l, mid, pro); modify(p<<1|1, mid+1, r, pro); } } } double query(int p, int pos) { if (e[p].l == e[p].r) { return e[p].pro; } else { push_down(p); int mid = (e[p].l + e[p].r) >> 1; if (pos <= mid) return query(p<<1, pos); else return query(p<<1|1, pos); } } int main( ) { int l, r; double ret; while (scanf("%d %d", &N, &M) == 2) { idx = -1; ret = 0.0; for (int i = 1; i <= N; ++i) { scanf("%d %d %d %d", &t[i].x, &t[i].H, &t[i].pl, &t[i].pr); H[++idx] = t[i].x, H[++idx] = t[i].x - t[i].H; H[++idx] = t[i].x + t[i].H; } for (int i = 1; i <= M; ++i) { scanf("%d %d", &m[i].x, &m[i].fee); H[++idx] = m[i].x; } sort(H, H+idx+1); idx = unique(H, H+idx+1)-H; build(1, 0, idx-1); for (int i = 1; i <= N; ++i) { l = bsearch(0, idx-1, t[i].x-t[i].H); r = bsearch(0, idx-1, t[i].x) - 1; modify(1, l, r, 1-t[i].pl/100.0); l = bsearch(0, idx-1, t[i].x) + 1; r = bsearch(0, idx-1, t[i].x+t[i].H); modify(1, l, r, 1-t[i].pr/100.0); } for (int i = 1; i <= M; ++i) { ret += m[i].fee * query(1, bsearch(0, idx-1, m[i].x)); } printf("%.4lf\n", ret); } return 0; }