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;
Calculate the maximum profit that Vasya can earn by taking a consecutive segment of tasks.
Input
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; }