现在的位置: 首页 > 综合 > 正文

HDU-Wind 离散化+线段树

2012年11月07日 ⁄ 综合 ⁄ 共 1845字 ⁄ 字号 评论关闭

题意为给定了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;
}

抱歉!评论已关闭.