洛谷

Codeforces


我竟然能在有生之年踩标算。


思路

首先考虑暴力:枚举左右端点直接计算。

考虑记录\(sum_x=\sum_{i=1}^x c_i\),设选\([l,r]\)时那个奇怪东西的平方为\(f(l,r)\),使劲推式子:

\[ans_{l,r}=(r-l+1)\times a-sum_r+sum_{l-1}-f(l,r)\\
ans_{l,r}+l\times a-a-sum_{l-1}=r\times a-sum_r-f(l,r)\\
ans_{l,r}+l\times a-a-sum_{l-1}=F_r-(\max_{i=l+1}^r\{d_{i}-d_{i-1}\})^2
\]

其中\(F_r=r\times a-sum_r\)。

发现左边只和\(l\)有关,所以可以考虑枚举\(l\),用数据结构维护右边的最大值。

然而右边有一个\(\max\)较为麻烦,怎样在移动左端点时快速更新呢?

考虑\(\max\)在左端点一定时单调不降,所以左端点每次往左移一格,只会对连续的一部分\(r\)造成影响,将他们的\(\max\)弄成一样的。

既然一样了,那就可以记录一个\(\max\{F_r\}\),然后把它们并在一起。

用一个单调栈记录\(r\),每次\(l\)往左移一位,就把一堆满足\(\max<d_{l+1}-d_l\)的\(r\)缩在一起,记录它们的\(\max \{F_r\}\)。

栈里每个元素也要存自己右边的\(F_r-(\max_{i=l+1}^r\{d_{i}-d_{i-1}\})^2\)的最大值,用来统计答案。

复杂度显然是\(O(n)\)的。


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 303030
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
inline void print(register int x)
{
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n;ll a;
ll sum[sz];
ll d[sz];
ll F[sz]; struct hh
{
ll f;
ll mx;
ll mxr;
}s[sz];
int top;
inline ll sq(ll x){return x*x;} int main()
{
file();
read(n,a);
ll x;
rep(i,1,n) read(d[i],x),sum[i]=sum[i-1]+x,F[i]=a*i-sum[i];
ll ans=max(a-sum[n]+sum[n-1],0ll);
s[++top]=(hh){F[n],0,F[n]};
s[0].mxr=-1e15;
drep(i,n-1,1)
{
ll mxF=-1e15;
while (top&&s[top].mx<=d[i+1]-d[i]) chkmax(mxF,s[top].f),s[top]=(hh){0,0,0},--top;
if (mxF!=-1e15) {++top;s[top]=(hh){mxF,d[i+1]-d[i],max(mxF-sq(d[i+1]-d[i]),s[top-1].mxr)};}
++top;s[top]=(hh){F[i],0,max(F[i],s[top-1].mxr)};
chkmax(ans,s[top].mxr-a*i+a+sum[i-1]);
}
cout<<ans;
return 0;
}

Codeforces 1107G Vasya and Maximum Profit [单调栈]的更多相关文章

  1. [Educational Round 59][Codeforces 1107G. Vasya and Maximum Profit]

    咸鱼了好久...出来冒个泡_(:з」∠)_ 题目连接:1107G - Vasya and Maximum Profit 题目大意:给出\(n,a\)以及长度为\(n\)的数组\(c_i\)和长度为\( ...

  2. Codeforces 1107G Vasya and Maximum Profit 线段树最大子段和 + 单调栈

    Codeforces 1107G 线段树最大子段和 + 单调栈 G. Vasya and Maximum Profit Description: Vasya got really tired of t ...

  3. CodeForces 1107 - G Vasya and Maximum Profit 线段树

    题目传送门 题解: 枚举 r 的位置. 线段树每个叶子节点存的是对应的位置到当前位置的价值. 每次往右边移动一个r的话,那么改变的信息有2个信息: 1. sum(a-ci) 2.gap(l, r) 对 ...

  4. Codeforces 802I Fake News (hard) (SA+单调栈) 或 SAM

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026184.html 题目传送门 - Codeforces 802I 题意 求一个串中,所有本质不同子串的出现次 ...

  5. Educational Codeforces Round 23 D. Imbalanced Array 单调栈

    D. Imbalanced Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. codeforces 817 D. Imbalanced Array(单调栈+思维)

    题目链接:http://codeforces.com/contest/817/problem/D 题意:给你n个数a[1..n]定义连续子段imbalance值为最大值和最小值的差,要你求这个数组的i ...

  7. codeforces1107G Vasya and Maximum Profit 【模拟】

    题目分析: 前缀和啥的模拟一下就行了. 代码: #include<bits/stdc++.h> using namespace std; ; int n,x,d[maxn],sta[max ...

  8. Codeforces gym 100971 D. Laying Cables 单调栈

    D. Laying Cables time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. Maximum Xor Secondary CodeForces - 281D (单调栈)

    Bike loves looking for the second maximum element in the sequence. The second maximum element in the ...

随机推荐

  1. FILE SIGNATURES TABLE

    FILE SIGNATURES TABLE 16 December 2017 This table of file signatures (aka "magic numbers") ...

  2. 本地测试使用Tomcat,生产环境使用GlassFish。

    总结:Tomcat8 = javaee7规范(servlet3.1 + jsp2.3 + el3.0 + websocket1.0) + java7 [配置初始化参数使用jdk8编译]conf/web ...

  3. 《Python数据可视化编程实战》

    第一章:准备工作环境 WinPython-32bit-3.5.2.2Qt5.exe 1.1 设置matplotlib参数 配置模板以方便各项目共享 D:\Bin\WinPython-32bit-3.5 ...

  4. pyqt5-QWidget坐标系统和大小

    获取坐标和尺寸: 坐标的获取视频教程:https://v.qq.com/x/page/t085892mzh9.html  x()    y()   返回控件的坐标 相对于父控件的坐标(窗口框架左上角) ...

  5. SSR搭建服务器

    SSR搭建服务器一站式教程:https://ssr.tools/252

  6. 洛谷P1972 【[SDOI2009]HH的项链】

    这道题想了很久,发题解是为了理解的更深刻一点...(管理放我过好嘛qwq) 步入正题:这道题应该是很多做法,我选择的是离线+树状数组. 首先输入数组.用fisrt数组先记录元素最开始出现的位置,对应的 ...

  7. steps/train_sat.sh

    <<LDA_MLLT_fMLLR三音素HMM的训练流程图.vsdx>>    

  8. json数据的处理和转化(loads/load/dump/dumps)

    import requests import json url='https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%8 ...

  9. FLASK-----基本知识(一)

    中文文档(http://docs.jinkan.org/docs/flask/) 英文文档(http://flask.pocoo.org/docs/0.11/) FLASK介绍 Flask是一个基于P ...

  10. AbstractQueuedSynchronizer的简单介绍

    AbstractQueuedSynchronizer简称为AQS.大多数开发者不会直接使用AQS,标准同步器类的集合能够满足绝大多数情况的需求. 1.AbstractQueuedSynchronize ...