CF1137E 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:

Some number of cars are added to the head of the train;
Some number of cars are added to the tail of the train;
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 A_iA
i

for each car (where ii is a car index), which is calculated as follows:

At the beginning of the trip A_i=0A
i

=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 A_iA
i

value b + (i - 1) \cdot 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 A_iA
i

is minimal. Since there is a lot of cars, Vasya asked you to write a program that answers his question.

输入格式
The first line contains two integers nn and mm ( 1 \leq n \leq 10^91≤n≤10
9
, 1 \leq m \leq 300,0001≤m≤300000 ), the number of cars in the train at the time of departure from the station and the number of stations, respectively.

Next mm lines contain the descriptions of events. Each event is one of the following three types:

" 11 kk " ( 1 \le k \le 10^91≤k≤10
9
), add kk cars to the head of the train
" 22 kk " ( 1 \le k \le 10^91≤k≤10
9
), add kk cars to the tail of the train
" 33 bb ss " ( 1 \le b, s \le 10^91≤b,s≤10
9
), recalculate the convenience of all train cars.
It is guaranteed that at any time the train length does not exceed 10^910
9
. Also it’s guaranteed that the integers A_iA
i

will not grow too high. Formally, it’s guaranteed that if we sum the largest addition over all events of the 33 -rd type (that is, b + (n - 1) \cdot sb+(n−1)⋅s , where nn is the number of cars at that moment) then the acquired sum would be at most 10^{18}10
18
.

输出格式
After each of the mm queries print two integers: jj and A_jA
j

— the number of the car closest to the head of the train, such that its value A_jA
j

is minimal, and the value A_jA
j

itself.

题意翻译
题目描述
给出一个序列a_ia
i

,初始有nn个00。mm次操作,操作有33种:

1\ k(1 \leq k \leq 10^9)1 k(1≤k≤10
9
):在序列开头加入kk个00

2\ k(1 \leq k \leq 10^9)2 k(1≤k≤10
9
):在序列末尾加入kk个00

3\ b\ s(1 \leq b , s \leq 10^9)3 b s(1≤b,s≤10
9
):对序列的所有元素做加法,给序列的第ii个元素加上b + s(i-1)b+s(i−1)

你需要在每一次操作过后输出当前序列中最小值位置和它的值。如果存在多个最小值则只考虑位置最靠前的。

输入格式
第一行两个正整数n(1 \leq n \leq 10^9) , m(1 \leq m \leq 300000)n(1≤n≤10
9
),m(1≤m≤300000)

接下来mm行每行22到33个正整数描述一个操作

输出格式
对于每一次操作输出一行两个正整数分别表示最小值位置和最小值。

输入输出样例
输入 #1复制
1 8
1 1
3 1 1
3 1 1
2 1
2 1
3 1 1
2 1
3 1 5
输出 #1复制
1 0
1 1
1 2
3 0
3 0
1 3
5 0
1 4
说明/提示
Initially the train consists of one car with A_1 = 0A
1

=0 , let’s denote train as [0][0] for simplicity.
After adding one car to the head, train is [0, 0][0,0] .
After recalculation of values with parameters b=1, s=1b=1,s=1 , train is [1, 2][1,2] .
After another recalculation of values with the parameters b=1, s=1b=1,s=1 , train is [2, 4][2,4] .
After adding one car to the end, train is [2, 4, 0][2,4,0] .
After another adding one car to the end, train is [2, 4, 0, 0][2,4,0,0] .
After recalculation of values with parameters b=1b=1 , s=1s=1 , train is [3, 6, 3, 4][3,6,3,4] .
After adding one car to the end, train is [3, 6, 3, 4, 0][3,6,3,4,0] .
After recalculation of values with parameters b=1b=1 , s=5s=5 , train is [4, 12, 14, 20, 21][4,12,14,20,21] .

思路

首先,我们注意到,每次加进去的一组0都是一起增加的,所以我们只需要关心这组0中的第一个(因为后面的肯定会永远大于等于第一个)。

然后我们又注意到,如果在最前面加入一些0,那么除了第一个以外的都永远不会是最大的,那么就相当于让所有A_i=0A
i
​ =0。

所以我们只需要关心2和3两个操作。

我们把所有(x,A_x)(x,A
x
​ )转化到二维平面上,然后维护一条向左下凸的折线,显然不在这个折线上的就永远不会是答案了。实际上答案就是折线上最后的点,就是右下角那个。

于是2操作就是加个点,然后和求凸包差不多,会删掉末尾的一些点。

3操作的话,我们发现经过操作之后所有线段的斜率都会变大,所以经过操作后凸折线的最后若干个点可能会“翘起来”,所以我们只需要从后往前,把那些“翘起来”的点删掉就行了。

代码

#include<cstdio>
#define N 1023000
#define ll long long
#define double long double
const double eps=1e-6;
struct Point{
    ll x,y;
    Point (ll _x=0,ll _y=0) : x(_x),y(_y) {}
    Point operator - (const Point &B) const {return Point(x-B.x,y-B.y);}
    double operator * (const Point &B) const {return (double)x*B.y-(double)y*B.x;}
}stk[N];
int top;ll k,b;
ll calc(Point A) {return A.y+k*A.x+b;}
int read(){
    int n=0;char a;bool z=false;
    while(a=getchar())
    {
        if (a>'9'||a<'0')
            if (z) break;
            else continue;
        if (!z) z=true;
        n=(n<<3)+(n<<1)+(a^48);
    }
    return n;
}
int main()
{
    ll n=read();int Q=read(),opt;Point now;
    stk[top=1]=Point();
    while(Q--)
    {
        opt=read();
        switch(opt)
        {
            case 1:stk[top=1]=Point();n+=read();k=b=0;break;
            case 2:now=Point(n,-(n*k+b));n+=read();
                while(top>1&&(now-stk[top-1])*(stk[top]-stk[top-1])>-eps) --top;
                stk[++top]=now;break;
            case 3:b+=read();k+=read();break;
        }
        while(top>1&&calc(stk[top])>=calc(stk[top-1])) --top;
        printf("%lld %lld\n",stk[top].x+1,calc(stk[top]));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值