题目

分析

\(s[i]\)表示a前缀和。

设\(f[i]\)表示做完了1~i的友谊颗粒的最优值(不一定选i),那么转移方程为

\[f[i]=max\{f[i-1],max\{f[j]-s[i]+s[j]+\dfrac{(i-j)(i-j+1)}{2}\}\}$$,用斜率优化来处理这个。
类似的,设$g_i$表示做完了i~n的友谊颗粒的最优值(不一定选i),
将a翻转,像f一样做一遍,再将g翻转就可以了。
对于询问(p,x),如果我们不选择p,那么答案就是$f[i-1]+g[i+1]$
如果我们选择了p,我们再设$F[i]$表示,必选i的最优值。
$$F[i]=max\{f[j]+g[k]+\dfrac{(k-j+1)(k-j+2)}{2}\}(j<i<k)\]

时间复杂度是\(O(N^2)\)

如何可以更快的求出\(F[i]\)呢,

分治,假设当前做到\([l,r]\),左端点\([l,mid]\),i和右端点在\([mid+1,r]\)

\(tmp[i]\)表示做完了左端点~i的友谊颗粒,且必选i的最优值

我们将\([l-1,mid-1]\)的端点扔进斜率优化的单调栈,扫一遍\([mid+1,r]\)求出tmp,

\[tmp[i]=max\{f[j]+g[i+1]+\dfrac{(i-j+1)(i-j+2)}{2}\}(j\in{[l-1,mid-1]}<i\in{[mid+1,r]})
\]

那么\(F[i]\)就是当前区间\(tmp[i]\)的后缀max

因为只考虑了i在\([mid+1,r]\)的情况,反过来做一遍就可以了。

那么选择了p的的最优值就是\(F[p]+a[p]-x\)

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=1000005;
#define rev(h) for(int i=1;i<=n/2;i++) swap(h[i],h[n-i+1])
#define val(h,j,k) 1ll*(h[j]-h[k]+s[j]-s[k]-1ll*j*1.0/2+1ll*k*1.0/2+1ll*j*j*1.0/2-1ll*k*k*1.0/2)*1.0/(j-k)
int n,m,t[N],top;
long long a[N],s[N],f[N],g[N],F[N],tmp[N];
void dg(long long *f,long long *g,int l,int r)
{
if(l==r)
{
F[l]=max(F[l],f[l-1]+g[l+1]+1-a[l]);
return;
}
int mid=(l+r)>>1;
top=0;
for(int i=l-1;i<=mid;i++)
{
for(;top>1 && val(f,i,t[top])>=val(f,t[top],t[top-1]);) top--;
t[++top]=i;
}
for(int i=mid+1;i<=r;i++)
{
for(;top>1 && val(f,t[top],t[top-1])<=i;) top--;
int j=t[top];
tmp[i]=f[j]-(s[i]-s[j])+1ll*(i-j)*(i-j+1)/2+g[i+1];
}
for(int i=r-1;i>=mid+1;i--) tmp[i]=max(tmp[i],tmp[i+1]);
for(int i=r;i>=mid+1;i--) F[i]=max(F[i],tmp[i]);
dg(f,g,l,mid),dg(f,g,mid+1,r);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),s[i]=s[i-1]+a[i],F[i]=-a[i]+1;
t[top=1]=0;
for(int i=1;i<=n;i++)
{
for(;top>1 && val(f,t[top],t[top-1])<=i;) top--;
int j=t[top];
f[i]=max(f[j]-(s[i]-s[j])+1ll*(i-j)*(i-j+1)/2,f[i-1]);
for(;top>1 && val(f,i,t[top])>=val(f,t[top],t[top-1]);) top--;
t[++top]=i;
}
rev(a);
t[top=1]=0;
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
for(int i=1;i<=n;i++)
{
for(;top>1 && val(g,t[top],t[top-1])<=i;) top--;
int j=t[top];
g[i]=max(g[j]-(s[i]-s[j])+1ll*(i-j)*(i-j+1)/2,g[i-1]);
for(;top>1 && val(g,i,t[top])>=val(g,t[top],t[top-1]);) top--;
t[++top]=i;
}
rev(a);
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
rev(g);
dg(f,g,1,n);
rev(a);
rev(g);
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
rev(F);
rev(f);
dg(g,f,1,n);
rev(F);
rev(g);
rev(f);
rev(a);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
long long p,x;
scanf("%lld%lld",&p,&x);
printf("%lld\n",max(f[p-1]+g[p+1],F[p]+a[p]-x));
}
}

Atcoder Regular Contest 066 F genocide【JZOJ5451】的更多相关文章

  1. AtCoder Regular Contest 085 C HSI【概率论】

    AtCoder Regular Contest 085 C HSI 没学概率论还不怎么看得懂,虽然感觉不难,其实明明可以猜出来的..... 参考博客:https://www.cnblogs.com/g ...

  2. AtCoder Regular Contest 066 F Contest with Drinks Hard

    题意: 你现在有n个题目可以做,第i个题目需要的时间为t[i],你要选择其中的若干题目去做.不妨令choose[i]表示第i个题目做不做.定义cost=∑(i<=n)∑(i<=j<= ...

  3. AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

    AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...

  4. AtCoder Beginner Contest 137 D题【贪心】

    [题意]一共有N个任务和M天,一个人一天只能做一个任务,做完任务之后可以在这一天之后的(Ai-1)天拿到Bi的工资,问M天内最多可以拿到多少工资. 链接:https://atcoder.jp/cont ...

  5. 【AtCoder Regular Contest 082 F】Sandglass

    [链接]点击打开链接 [题意] 你有一个沙漏. 沙漏里面总共有X单位的沙子. 沙漏分A,B上下两个部分. 沙漏从上半部分漏沙子到下半部分. 每个时间单位漏1单位的沙子. 一开始A部分在上面.然后在r1 ...

  6. 【推导】【模拟】AtCoder Regular Contest 082 F - Sandglass

    题意:有个沙漏,一开始bulb A在上,bulb B在下,A内有a数量的沙子,每一秒会向下掉落1.然后在K个时间点ri,会将沙漏倒置.然后又有m个询问,每次给a一个赋值ai,然后询问你在ti时刻,bu ...

  7. 【arc077f】AtCoder Regular Contest 077 F - SS

    题意 给你一个形如"SS"的串S,以及一个函数\(f(x)\),\(x\)是一个形如"SS"的字符串,\(f(x)\)也是一个形如"SS"的 ...

  8. 【构造】AtCoder Regular Contest 079 F - Namori Grundy

    对每个点的取值都取最小的可能值. 那个图最多一个环,非环的点的取值很容易唯一确定. 对于环上的点v,其最小可能取值要么是mex{c1,c2,...,ck}(ci这些是v直接相连的非环点)(mex是). ...

  9. 【AtCoder Regular Contest 076 F】Exhausted (贪心)

    Description 机房里有M台电脑排成一排,第i台电脑的坐标是正整数i. 现在有N个OIer进入了机房,每个OIer需要一台电脑来学tui习ji,同时每个OIer对自己电脑所处的坐标范围有一个要 ...

随机推荐

  1. run.sh

    1.run.sh   文件  ./run.sh start启动    ./run.sh stop 停止    ./run.sh restart重启     ./run.sh install安装     ...

  2. [Python3] 038 函数式编程 偏函数

    目录 函数式编程 之 偏函数 1. 关于强制类型转换 int 的补充 2. 利用 int 新建函数 3. functools.partial 函数式编程 之 偏函数 1. 关于强制类型转换 int 的 ...

  3. 查找担保圈-step3-获取担保圈路径

    USE [test] GO /****** Object: StoredProcedure [dbo].[p01_get_group_path] Script Date: 2019/7/8 14:40 ...

  4. GitHub从小白到熟悉<一>

    注册开始

  5. python3.7环境下创建app,运行Django1.11版本项目报错SyntaxError: Generator expression must be parenthesized

    咳咳!!! 今天用命令行创建django项目中的app应用,出现了这样一个错误 这个错误在python3.6版本下安装运行django 1.11版本正常运行,但python3.7版本下运行django ...

  6. API 网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd

    前几天拜读了 OpsGenie 公司(一家致力于 Dev & Ops 的公司)的资深工程师 Turgay Çelik 博士写的一篇文章(链接在文末),文中介绍了他们最初也是采用 Nginx 作 ...

  7. sql server 函数详解(4)日期和时间函数

    时间和日期函数第一部分 时间和日期函数第二部分

  8. 第六篇 ajax

    加载异步数据 6-1 加载异步数据 XMLHttpRequest--传统的JavaScript方法实现Ajax功能 6-1-a <!DOCTYPE html PUBLIC "-//W3 ...

  9. C++参数传递与STL

    C++参数传递与STL 这是一篇备忘录形式的内容,涉及到的内容比较基础 今天写了一个小算法,用一个set在函数间传递,记录各个函数中的结果.但是最后结果显示set中的元素是0个.查了一下才发现,用来C ...

  10. CF1151F Sonya and Informatics

    cf luogu 我们最终要的序列一定是前面全是0,后面全是1,假设总共\(m\)个0,那么这等价于前\(m\)位0的个数为\(m\).当然一开始可能数量没有\(m\) 那就把前\(m\)位0的数量作 ...