• Codeforces Round #545 (Div. 1) E. Train Car Selection


    Vasya likes to travel by train, but doesn't like when the car he travels in is located in the tail of the train.

    Vasya gets on the train at the station. The train consists of nn cars indexed from 11 to nn counting from the locomotive (head of the train). Three types of events occur while the train is moving:

    1. Some number of cars are added to the head of the train;
    2. Some number of cars are added to the tail of the train;
    3. Vasya recalculates the values of the convenience of the cars (read more about it below).

    At each moment of time we will index the cars from the head of the train, starting from 11. Note that when adding new cars to the head of the train, the indexing of the old ones may shift.

    To choose which car to go in, Vasya will use the value AiAi for each car (where ii is a car index), which is calculated as follows:

    • At the beginning of the trip Ai=0Ai=0, as well as for the new cars at the time of their addition.
    • During the next recalculation Vasya chooses some positive integers bb and ss and adds to all AiAi value b+(i1)sb+(i−1)⋅s.

    Vasya hasn't decided yet where he will get on the train and where will get off the train, so after each event of one of the three types he wants to know the least index of the car, such that its value AiAi is minimal. Since there is a lot of cars, Vasya asked you to write a program that answers his question.

    很容易可以发现,每次插入k个数时,其实只有第一个是有用的,而且当插入在队首时,可以直接将队列里面的所有值全部弹出。

    所以可以开一个单调递减的栈维护一下,每次只需要判断栈顶的值是否大于前一个的值即可。

    但是这样有一个问题,可能会出现一种情况,满足栈顶的值小于前一个,但是已经大于了前面的另一个值。

    这种情况很容易处理,只要我们加入值得判断一下,新加入的值超过前一个值的速度是否大于前一个的值超过再前一个的值即可。

    这样一来,这个栈就可以满足当一个值超过前一个值的时候,前一个值要么没超过再前一个的值,要么刚好超过,于是就能避免上述提到的情况。

    至于位置,B值和S值的维护都很简单,在此不加赘述。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 500000
    #define ll long long
    using namespace std;
    ll n,m,opt,k,b,s,K,B,S,kp[N],bp[N],sp[N],top,data[N],num,mp;
    ll gets(ll x){
        return B-bp[x]+(S-sp[x])*(kp[x]-1);
    }
    double getp(ll x,ll y){
        return (double)(gets(x)-gets(y))/(kp[y]-kp[x]);
    }
    int main(){
        scanf("%lld%lld",&n,&m);
        mp=m;
        top=1;
        num=1;
        data[1]=1;
        kp[1]=1;
        K=n;
        while (m--){
            scanf("%lld",&opt);
            if (opt==1){
                scanf("%lld",&k);
                num++;
                kp[num]=1;
                bp[num]=B;sp[num]=S;
                K+=k;
                top=1;
                data[1]=num;
                printf("1 0
    ");
            }
            if (opt==2){
                scanf("%lld",&k);
                num++;
                kp[num]=K+1;
                bp[num]=B;sp[num]=S;
                K+=k;
                if (gets(data[top])==0){
                    printf("%lld %lld
    ",kp[data[top]],0);
                    continue;
                }
                top++;
                data[top]=num;
                while (top>2&&getp(data[top-2],data[top-1])<=getp(data[top-1],data[top])){
                    data[top-1]=data[top];
                    top--;
                }
                printf("%lld %lld
    ",kp[data[top]],0);
            }
            if (opt==3){
                scanf("%lld%lld",&b,&s);
                B+=b;
                S+=s;
                while (top>1&&gets(data[top])>=gets(data[top-1]))
                    top--;
                printf("%lld %lld
    ",kp[data[top]],gets(data[top]));
            }
        }
        return 0;
    }
  • 相关阅读:
    数据库插入数据返回当前主键ID值方法
    兼容SQLSERVER、Oracle、MYSQL、SQLITE的超级DBHelper
    C# listview 单击列头实现排序 <二>
    C# ListView点击列头进行排序
    MessageBox.Show()的各种用法
    QT 删除文件指定目录
    hihoCoder 1015 KMP算法
    hiho一下 第五十周 (求欧拉路径)
    hdu
    hiho一下 第四十九周 欧拉路
  • 原文地址:https://www.cnblogs.com/Mohogany/p/13726636.html
Copyright © 2020-2023  润新知