zoukankan      html  css  js  c++  java
  • HDUWind 离散化+线段树

    题意为给定了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;
    }
  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/Lyush/p/2647994.html
Copyright © 2011-2022 走看看