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;

}

你可能感兴趣的:(HDU)