• Codeforces Round #107 (Div. 1) C Smart Cheater


    题目链接:Smart Cheater

    题意:一辆公交车共有 n 个车站,有 m 位乘客,已知所有车站的位置 x[i] 和每位乘客所乘车区间,两个车站间的车票价格为 x[i+1]-x[i]。对于每位乘客,售票员可以选择至多一段连续区间不售这段区间的票,并和乘客平分这个钱。但是每一相邻区间都有 p[i] 的概率出现监督员,如果监督员发现有乘客没有这段区间的车票,售票员就会被罚款 c。问售票员收到的钱的最大期望。

    题解:对于每一个乘客,每一个相邻区间是一样的,可以分别计算出每个区间一位乘客的期望价格为:(x[i+1]-x[i])/2-c*p[i]。现在问题转化为了多次查询某个区间内的最大连续子序列和,用线段树处理。线段树中存储四个信息:区间全部的和 sum_all、以左端点为连续区间起点的最大连续字段和 sum_l、以右端点为连续区间终点的最大连续字段和 sum_r、这个区间内的最大连续字段和 sum_ans。其区间内的最大连续字段和,要么是左子树的 sum_l,要么是右子树的 sum_r,或者是左子树的 sum_r + 右子树的 sum_l。

    #include <bits/stdc++.h>
    #define mid ((l+r)/2)
    #define lson (id<<1)
    #define rson ((id<<1)+1)
    using namespace std;
    
    int n,m,fine;
    int x[150005],p[1500005],on[300005],off[300005];
    double a[150005];
    struct node{
        int on,off;
    } pass[300005];
    
    struct Node{
        int l,r;
        double sum_l,sum_r,sum_all,sum_ans;
    } tre[150005*4];
    
    void build(int id,int l,int r){
        tre[id].l=l;
        tre[id].r=r;
        if(l==r){
            tre[id].sum_l=a[l];
            tre[id].sum_r=a[l];
            tre[id].sum_all=a[l];
            tre[id].sum_ans=a[l];
            return;
        }
        build(lson,l,mid);
        build(rson,mid+1,r);
        tre[id].sum_l=max(tre[lson].sum_l,tre[lson].sum_all+tre[rson].sum_l);
        tre[id].sum_r=max(tre[rson].sum_r,tre[rson].sum_all+tre[lson].sum_r);
        tre[id].sum_ans=max(max(tre[lson].sum_ans,tre[rson].sum_ans),tre[lson].sum_r+tre[rson].sum_l);
        tre[id].sum_all=tre[lson].sum_all+tre[rson].sum_all;
    }
    Node query(int id,int ql,int qr){
        if(ql==tre[id].l&&tre[id].r==qr){
            return tre[id];
        }
        int l=tre[id].l,r=tre[id].r;
        if(qr<=mid) return query(lson,ql,qr);
        if(ql>mid) return query(rson,ql,qr);
    
        Node New_l=query(lson,ql,mid);
        Node New_r=query(rson,mid+1,qr);
        Node res;
        res.sum_l=max(New_l.sum_l,New_l.sum_all+New_r.sum_l);
        res.sum_r=max(New_r.sum_r,New_r.sum_all+New_l.sum_r);
        res.sum_all=New_l.sum_all+New_r.sum_all;
        res.sum_ans=max(max(New_l.sum_ans,New_r.sum_ans),New_l.sum_r+New_r.sum_l);
        return res;
    }
    
    int main(){
        scanf("%d%d%d",&n,&m,&fine);
        for(int i=1;i<=n;i++) scanf("%d",&x[i]);
        for(int i=1;i<n;i++) scanf("%d",&p[i]);
        for(int i=1;i<=m;i++) scanf("%d%d",&pass[i].on,&pass[i].off);
        double ans=0;
        for(int i=1;i<n;i++){
            a[i+1]=1.0*(x[i+1]-x[i])/2.0-1.0*p[i]/100.0*fine;
        }
        build(1,1,n);
        for(int i=1;i<=m;i++){
            double res=query(1,pass[i].on+1,pass[i].off).sum_ans;
            ans+=max(res,0.0);
        }
    
        printf("%.9f
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    docker/kubernetes国内源/镜像源解决方式
    logstash的filter之grok
    基于ambari搭建hadoop生态圈大数据组件
    Hadoop整体概述
    flume的配置详解
    Zabbix错误”zbx_mem_malloc(): out of memory”解决方法
    Windows环境下的RTKPlot_Qt版本编译时遇到的问题和解决方法
    基于 win7下虚拟机的 GNSS-SDR安装过程
    博客文章搬迁同步声明
    RTKLIB源码解析(一)——单点定位(pntpos.c)
  • 原文地址:https://www.cnblogs.com/N-Psong/p/10270330.html
Copyright © 2020-2023  润新知