CodeForces 151E Smart Cheater(线段树)

题目链接

E. Smart Cheater
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

I guess there's not much point in reminding you that Nvodsk winters aren't exactly hot. That increased the popularity of the public transport dramatically. The route of bus 62 has exactly n stops (stop 1 goes first on its way and stop n goes last). The stops are positioned on a straight line and their coordinates are 0 = x1 < x2 < ... < xn.

Each day exactly m people use bus 62. For each person we know the number of the stop where he gets on the bus and the number of the stop where he gets off the bus. A ticket from stop a to stop b (a < b) costs xb - xa rubles. However, the conductor can choose no more than one segment NOT TO SELL a ticket for. We mean that conductor should choose C and D (С <= D) and sell a ticket for the segments [A, C] and [D, B], or not sell the ticket at all. The conductor and the passenger divide the saved money between themselves equally. The conductor's "untaxed income" is sometimes interrupted by inspections that take place as the bus drives on some segment of the route located between two consecutive stops. The inspector fines the conductor by c rubles for each passenger who doesn't have the ticket for this route's segment.

You know the coordinated of all stops xi; the numbers of stops where the i-th passenger gets on and off, ai and bi (ai < bi); the fine c; and also pi — the probability of inspection on segment between the i-th and the i + 1-th stop. The conductor asked you to help him make a plan of selling tickets that maximizes the mathematical expectation of his profit.

Input

The first line contains three integers n, m and c (2 ≤ n ≤ 1.5·105, 1 ≤ m ≤ 3·105, 1 ≤ c ≤ 104).

The next line contains n integers xi (0 ≤ xi ≤ 109, x1 = 0, xi < xi + 1) — the coordinates of the stops on the bus's route.

The third line contains n - 1 integer pi (0 ≤ pi ≤ 100) — the probability of inspection in percents on the segment between stop i and stop i + 1.

Then follow m lines that describe the bus's passengers. Each line contains exactly two integers ai and bi (1 ≤ ai < bi ≤ n) — the numbers of stops where the i-th passenger gets on and off.

Output

Print the single real number — the maximum expectation of the conductor's profit. The answer will be considered correct if its relative or absolute error does not exceed 10 - 6.

Sample test(s)
Input
3 3 10
0 10 100
100 0
1 2
2 3
1 3
Output
90.000000000
Input
10 8 187
0 10 30 70 150 310 630 1270 2550 51100
13 87 65 0 100 44 67 3 4
1 10
2 9
3 8
1 5
6 10
2 7
4 10
4 5
Output
76859.990000000
Note

A comment to the first sample:

The first and third passengers get tickets from stop 1 to stop 2. The second passenger doesn't get a ticket. There always is inspection on the segment 1-2 but both passengers have the ticket for it. There never is an inspection on the segment 2-3, that's why the second passenger gets away with the cheating. Our total profit is (0 + 90 / 2 + 90 / 2) = 90.

题意:在一条直线上从左到右有N个站,已知每个点的坐标X[i]。汽车从第一个站开往第N个站。有M个乘客,已知每个乘客从ai站上,在bi站下。票价为X[bi]-X[ai]。对于每个乘客,售票员可以选择一个区间[l,r](也可以不选),不卖站l到站r这段区间的票,剩下的前售票员和乘客平分。对于第i个站到第i+1个站,有pi的概率(pi表示百分比)会被查,被查以后每有一个人没有这段路的票就罚售票员C。求售票员能赚到的钱的期望的最大值。

题解:

对于第i个人,售票员若不卖他区间[l,r]的票,他赚钱的期望为:

(X[r]-X[l])/2-(pl+......pr)*C/100

处理出p数组的前缀和数组sump

则上式可以写为:

X[r]/2-sump[r]*c/100  - x[l]/2+sump[l-1]*C/100

另a[r]=X[r]/2-sump[r]*c/100,b[l]=- x[l]/2+sump[l-1]*C/100

c[l,r]=a[r]+b[l]且l<r

我们可以用线段树维护一个区间中最大的 a,最大的b,和最大的c,然后O(lgn)完成一次查询。

代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<string.h>
#include<string>
#include<stdlib.h>
typedef __int64 LL;
typedef unsigned __int64 LLU;
const int nn=310000;
const int inf=0x3fffffff;
const LL inf64=(LL)inf*inf;
const double eps=1e-8;
using namespace std;
LL n,m,c;
LL x[nn],p[nn];
LL mv1[nn*4],mv2[nn*4];
LL mans[nn*4];
LL sum[nn];
void update(int id)
{
    mans[id]=mv1[2*id+1]+mv2[2*id];
    mans[id]=max(mans[id],mans[2*id+1]);
    mans[id]=max(mans[id],mans[2*id]);
    mv1[id]=max(mv1[2*id],mv1[2*id+1]);
    mv2[id]=max(mv2[2*id],mv2[2*id+1]);
}
void build(int id,int l,int r)
{
    if(l==r)
    {
        mv1[id]=50*x[r]-c*sum[r-1];
        mv2[id]=-50*x[l]+c*sum[l-1];
        mans[id]=0;
        return ;
    }
    int mid=(l+r)/2;
    build(2*id,l,mid);
    build(2*id+1,mid+1,r);
    update(id);
}
vector<int>ve;
void solve(int id,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {
        ve.push_back(id);
        return ;
    }
    int mid=(l+r)/2;
    if(L<=mid)
        solve(2*id,l,mid,L,R);
    if(R>mid)
        solve(2*id+1,mid+1,r,L,R);
}
int main()
{
    int i;
    LL l,r;
    while(scanf("%I64d%I64d%I64d",&n,&m,&c)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%I64d",&x[i]);
        }
        sum[0]=0;
        for(i=1;i<n;i++)
        {
            scanf("%I64d",&p[i]);
            sum[i]=sum[i-1]+p[i];
        }
        build(1,1,n);
        LL ans=0;
        LL m1,m2,m3;
        m1=m2=m3;
        LL a1,a2,a3;
        for(i=1;i<=m;i++)
        {
            scanf("%I64d%I64d",&l,&r);
            ve.clear();
            solve(1,1,n,l,r);
            m1=mv1[ve[0]];
            m2=mv2[ve[0]];
            m3=mans[ve[0]];
            for(int j=1;j<(int)ve.size();j++)
            {
                a3=max(m3,mans[ve[j]]);
                a3=max(a3,mv1[ve[j]]+m2);
                a1=max(m1,mv1[ve[j]]);
                a2=max(m2,mv2[ve[j]]);
                m1=a1,m2=a2,m3=a3;
            }
            ans+=m3;
        }
        printf("%lf\n",ans/100.0);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值