• ZJNU 2479


    浙江师范大学第十八届大学生程序设计竞赛(重现) H - 车辆探测器

    ZJNU 2479 - 车辆探测器


    题意

    (n)辆汽车在(x)轴负半轴排成一列以每秒(1)米的速度匀速向(x)正半轴行驶,第(i)辆汽车的初始位置为(a[i])

    (m)个车辆探测器,探测范围为(pm r[i])的探测器被放在(x)正半轴((r[i],0))的位置。

    只要每个车辆探测器的探测范围内有车存在,那么每秒会消耗(P)焦耳的能量。

    如果原本探测范围内没有车存在,车辆探测器会关闭,一旦有车进入探测范围,探测器每次打开需要消耗(C)焦耳的能量。

    对于每个探测器,分别求出它们消耗的能量。

    限制

    (1leq nleq 10^5)

    (1leq mleq 10^5)

    (1leq P,Cleq 10^6)

    (-2 imes 10^6le a[i]lt a[i+1]lt 0)

    (1le r[i]le 10^8)




    思路

    一下子一年就过去了呢,这题去年正式比赛时没有过多少人,借这次重现赛重新写一遍整理思路

    当时应该是树状数组过的,现在想了下好像差分数组直接就可以做,还更方便

    (一年过去了思维还是没有什么质的飞跃呢……)


    换句话说,对于每个探测范围为(pm r)的探测器,其探测的左右最大距离即为(2r)

    所以只要有两辆车的间隔(gt 2r),那么探测器就会多消耗(C)焦耳的能量


    假设探测器从第(1)辆车进入探测范围开始,到第(n)辆车离开探测范围结束,它都在进行工作,那么总共消耗的能量为(P imes(a[n]-a[1]+2r))

    然后我们需要求出所有(gt 2r)的间隔减去(2r)后的总和,这就是探测器不进行工作的时间长度


    对于所有的(n-1)个间隔,先设(gt 2r)的间隔数量为(upperCount)

    如果我们能够找出所有(gt 2r)的间隔的长度总和(uselessLen),就可以通过(uselessLen-2r imes upperCount)来得到上述的探测器不进行工作的时间长度


    对于(gt 2r)的间隔数量与(gt 2r)的间隔长度总和,由于只存在询问不存在修改,故可以直接通过建立两个前缀和数组

    如果某两辆车的间隔为(d),可以在维护数量的数组里(d)位置(+1),在维护长度的数组里(d)位置(+d)

    在取值时,(arrayCount[2r])可以表示长度(le 2r)的间隔数量,故(upperCount=(n-1)-arrayCount[2r])

    (arrayLen[2r])可以表示长度(le 2r)的间隔长度总和,故(uselessLen=(a[n]-a[1]+ar)-arrayLen[2r]-2r imes upperCount)




    程序

    (注意有些读入挂可能会WA Case 1)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int a[100050];
    ll ar1[2000050],ar2[2000050];
    
    int main()
    {
        int n,m,P,C;
        scanf("%d%d%d%d",&n,&m,&P,&C);
        
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(i!=1)
            {
                int d=a[i+1]-a[i];
                ar1[d]++;
                ar2[d]+=d;
            }
        }
        
        for(int i=1;i<=2000000;i++)
        {
            ar1[i]+=ar1[i-1];
            ar2[i]+=ar2[i-1];
        }
        
        int TotalLen=a[n]-a[1];
        for(int i=1;i<=m;i++)
        {
            int r;
            scanf("%d",&r);
            if(r>=1000000) //这种探测器不会关闭,不需要讨论
            {
                printf("%lld
    ",1LL*P*(TotalLen+2*r)+C);
                continue;
            }
            int upperCount=(n-1)-ar1[2*r]; //求出>2r的间隔数量
            int uselessLen=TotalLen-ar2[2*r]; //求出>2r的间隔长度-2r后的和
            int Len=(TotalLen+2*r)-(uselessLen-2*r*upperCount); //可行长度
            printf("%lld
    ",1LL*P*Len+1LL*C*(upperCount+1)); //一开始就需要进行一次开启
        }
        
        return 0;
    }
    

  • 相关阅读:
    Java中会存在内存泄漏吗,请简单描述。
    什么是类加载器
    通俗易懂 索引、单列索引、复合索引、主键、唯一索引、聚簇索引、非聚簇索引、唯一聚簇索引 的区别与联系
    Redis真的那么好用吗
    java中public,private,protected和default的区别
    聚集和非聚集索引
    我以为我对Mysql索引很了解,直到我遇到了阿里的面试官(转)
    Java中存储金额用什么数据类型
    InnoDB在MySQL默认隔离级别下解决幻读
    android应用程序第一次启动时显示引导界面
  • 原文地址:https://www.cnblogs.com/stelayuri/p/14027383.html
Copyright © 2020-2023  润新知