zoukankan      html  css  js  c++  java
  • codeforce 139E

    成段更新+离散化才能过,数据好强。。

    单点更新挂在了test27,下次做到成段更新再来做!

    
    
    /*
    期望=存活概率*点权值/100
    ans=sum(期望)
    离散化树木权值,数轴统计累加可能倒下的树木概率(直接加权值即可)
    线段树单点,sum[rt]维护在这个区间中所有蘑菇的存活期望值
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 100005
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define ll long long 
    using namespace std;
    struct Tree{
        int pos,h,pl,pr;//坐标,高度,左概率,右概率
    }tree[maxn];
    struct Mushroom{
        int pos,w;//蘑菇坐标,蘑菇权值
    }mushroom[maxn];
    int axis[maxn<<3],cnt,tot;
    double poss[maxn<<3];//排序后的坐标点,数轴[1,maxn<<3]上存活概率
    double sum[maxn<<2];
    void build(int l,int r,int rt){
        sum[rt]=0;
        if(l==r)
            return;
        int m=l+r>>1;
        build(lson);
        build(rson);
    }
    inline pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void update(int pos,double val,int l,int r,int rt){
        sum[rt]+=val;
        if(l==r) return;
        int m=l+r>>1;
        if(pos<=m) update(pos,val,lson);
        else update(pos,val,rson);
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        cnt=0;
            for(int i=1;i<=n;i++){
                scanf("%d%d%d%d",&tree[i].pos,&tree[i].h,&tree[i].pl,&tree[i].pr);
                axis[cnt++]=tree[i].pos;
                axis[cnt++]=tree[i].pos-tree[i].h;
                axis[cnt++]=tree[i].pos+tree[i].h;
            }
            for(int i=1;i<=m;i++){
                scanf("%d%d",&mushroom[i].pos,&mushroom[i].w);
                axis[cnt++]=mushroom[i].pos;
            }
        
            sort(axis,axis+cnt);
            int tot=unique(axis,axis+cnt)-axis;//离散化
            for(int i=1;i<=tot;i++)//一开始所有的坐标上存活概率都是1
                poss[i]=1;
            //每个点找坐标logn,打标记最多n,复杂度O(n*n)
            for(int i=1;i<=n;i++){
                int pos=lower_bound(axis,axis+tot,tree[i].pos)-axis+1;
                int posl=lower_bound(axis,axis+tot,tree[i].pos-tree[i].h)-axis+1;
                int posr=lower_bound(axis,axis+tot,tree[i].pos+tree[i].h)-axis+1;
                for(int j=posl;j<pos;j++)//倒在左区间的概率
                    poss[j]*=1-(double)tree[i].pl/100;
                for(int j=pos+1;j<=posr;j++)//倒在右区间的概率
                    poss[j]*=1-(double)tree[i].pr/100;
            }
            //至此统计完概率,开始建立线段树
            build(1,tot,1);
            for(int i=1;i<=m;i++){
                int pos=lower_bound(axis,axis+tot,mushroom[i].pos)-axis+1;
                update(pos,mushroom[i].w*poss[pos],1,tot,1);//把权值*期望更新到线段树中
            }
            printf("%.4lf
    ",sum[1]);
        
        return 0;
    }
    
    
    
     
  • 相关阅读:
    【BZOJ3626】【LNOI2014】—Lca(树链剖分)
    【BZOJ2434】【NOI2011】—阿狸的打字机(AC自动机+线段树)
    【UVA10498】—Happiness(线性规划/单纯形算法)
    【BZOJ4736】【清华集训2016】—温暖会指引我们前行(LCT)
    【BZOJ3451】【Tyvj1953】—Normal(点分治+NTT)
    【SCOI2019】—DAY2T1 湖之精灵的游戏(凸包+二分)
    【BZOJ4817】【SDOI2017】—树点涂色(LCT+树链剖分+线段树)
    【SCOI2019】—DAY2T1 RGB(容斥)
    Stargazer的分治讲义
    python datetime 模块
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9901990.html
Copyright © 2011-2022 走看看