Codeforces Contest 1107 problem G Vasya and Maximum Profit—— 枚举每个不可控制的量找它所对应区间的数的最大值

Vasya got really tired of these credits (from problem F) and now wants to earn the money himself! He decided to make a contest to gain a profit.

Vasya has n problems to choose from. They are numbered from 1 to n. The difficulty of the i-th problem is di. Moreover, the problems are given in the increasing order by their difficulties. The difficulties of all tasks are pairwise distinct. In order to add the i-th problem to the contest you need to pay ci burles to its author. For each problem in the contest Vasya gets a burles.

In order to create a contest he needs to choose a consecutive subsegment of tasks.

So the total earnings for the contest are calculated as follows:

if Vasya takes problem i to the contest, he needs to pay ci to its author;
for each problem in the contest Vasya gets a burles;
let gap(l,r)=maxl≤i<r(di+1−di)2. If Vasya takes all the tasks with indices from l to r to the contest, he also needs to pay gap(l,r). If l=r then gap(l,r)=0.
Calculate the maximum profit that Vasya can earn by taking a consecutive segment of tasks.

Input
The first line contains two integers n and a (1≤n≤3⋅105, 1≤a≤109) — the number of proposed tasks and the profit for a single problem, respectively.

Each of the next n lines contains two integers di and ci (1≤di,ci≤109,di<di+1).

Output
Print one integer — maximum amount of burles Vasya can earn.

Examples
inputCopy
5 10
1 15
5 3
6 11
7 2
11 22
outputCopy
13
inputCopy
3 5
1 8
2 19
3 11
outputCopy
0

题意:

给你n种题目,然后给你他们的难度di和花费ci,你能出一段区间的题目,出一道题目可以得到a元,但是要花费区间所有题目的价格,还要花费在这个区间里,相邻两个题目难度差值的平方的最大值,问你最后可以赚最多多少钱。

题解:

区间的变化,a的值和ci的和都是可以预处理出来的,那么我们需要考虑的就是d,我们枚举每一位上的d,记录它最远能够管辖的区间,sta存放的是到当前位置为止,有哪些开头可以管辖到当前位置,和他们最早能管辖到的位置的c的前缀和。举个例子:
在这里插入图片描述
有这三个位置,他们一定是单调递减的,因为如果有递增的话,前面那个小的d会被后面大的d取代掉,所以就变成这样。sta记录的就是10的位置和蓝色的线,5的位置和蓝色的线。
那如果现在来了一个6,他就能管辖到5所管辖到的位置,而且这就是为什么要用LIFO的原因。
在这里插入图片描述
之后我们还需要有一个东西可以自动排序蓝色线的最小值,在5被删掉的时候,蓝色的线也可以被删掉,因为它无法管辖到下一个位置了。那就用multiset。
其实也是看别人的代码想出来的

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pa pair<int,ll>
const int N=3e5+5;
ll d[N],c[N];
ll dis(int x)
{
    return (d[x+1]-d[x])*(d[x+1]-d[x]);
}
int main()
{
    int n;
    ll a,ans=0;
    scanf("%d%lld",&n,&a);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&d[i],&c[i]);
        ans=max(ans,a-c[i]);
        c[i]=c[i-1]+a-c[i];
    }
    stack<pa>st;
    multiset<ll>ms;
    for(int i=1;i<=n;i++)
    {
        if(!ms.empty())
            ans=max(ans,c[i]-*ms.begin());
        ll dist=dis(i),pre=c[i-1];
        while(!st.empty()&&dis(st.top().first)<=dist)
        {
            pre=min(pre,st.top().second);
            ms.erase(ms.find(st.top().second+dis(st.top().first)));
            st.pop();
        }
        st.push({i,pre});
        ms.insert(dist+pre);
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/88084667
今日推荐