Atcoder Regular Contest 066 F genocide【JZOJ5451】
题目
分析
\(s[i]\)表示a前缀和。
设\(f[i]\)表示做完了1~i的友谊颗粒的最优值(不一定选i),那么转移方程为
类似的,设$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,
\]
那么\(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】的更多相关文章
- AtCoder Regular Contest 085 C HSI【概率论】
AtCoder Regular Contest 085 C HSI 没学概率论还不怎么看得懂,虽然感觉不难,其实明明可以猜出来的..... 参考博客:https://www.cnblogs.com/g ...
- AtCoder Regular Contest 066 F Contest with Drinks Hard
题意: 你现在有n个题目可以做,第i个题目需要的时间为t[i],你要选择其中的若干题目去做.不妨令choose[i]表示第i个题目做不做.定义cost=∑(i<=n)∑(i<=j<= ...
- AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图
AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...
- AtCoder Beginner Contest 137 D题【贪心】
[题意]一共有N个任务和M天,一个人一天只能做一个任务,做完任务之后可以在这一天之后的(Ai-1)天拿到Bi的工资,问M天内最多可以拿到多少工资. 链接:https://atcoder.jp/cont ...
- 【AtCoder Regular Contest 082 F】Sandglass
[链接]点击打开链接 [题意] 你有一个沙漏. 沙漏里面总共有X单位的沙子. 沙漏分A,B上下两个部分. 沙漏从上半部分漏沙子到下半部分. 每个时间单位漏1单位的沙子. 一开始A部分在上面.然后在r1 ...
- 【推导】【模拟】AtCoder Regular Contest 082 F - Sandglass
题意:有个沙漏,一开始bulb A在上,bulb B在下,A内有a数量的沙子,每一秒会向下掉落1.然后在K个时间点ri,会将沙漏倒置.然后又有m个询问,每次给a一个赋值ai,然后询问你在ti时刻,bu ...
- 【arc077f】AtCoder Regular Contest 077 F - SS
题意 给你一个形如"SS"的串S,以及一个函数\(f(x)\),\(x\)是一个形如"SS"的字符串,\(f(x)\)也是一个形如"SS"的 ...
- 【构造】AtCoder Regular Contest 079 F - Namori Grundy
对每个点的取值都取最小的可能值. 那个图最多一个环,非环的点的取值很容易唯一确定. 对于环上的点v,其最小可能取值要么是mex{c1,c2,...,ck}(ci这些是v直接相连的非环点)(mex是). ...
- 【AtCoder Regular Contest 076 F】Exhausted (贪心)
Description 机房里有M台电脑排成一排,第i台电脑的坐标是正整数i. 现在有N个OIer进入了机房,每个OIer需要一台电脑来学tui习ji,同时每个OIer对自己电脑所处的坐标范围有一个要 ...
随机推荐
- 【VS开发】获得devcon.exe
1.获得devcon.exe 有两种方法,一是直接去网上下,不过下的很多64位的都不能用,二是自己装个ddk去安装目录下找,在WinDDK\7600.16385.1\tools\devcon下,当然还 ...
- Angular build编译内存溢出"JavaScript heap out of memory"的解决办法
关于最近使用angular build编译打包的时候,遇到内存溢出的突发情况,做一个简单记录 编译报错如下↓↓↓ 报错信息很直观地指出是内存溢出了.是什么导致了内存溢出呢?其根本原因在于 nodejs ...
- Emgu 学习(4) 使用指针访问图像内存
在原始图像最初的10行绘制一个颜色条 class Program { static void Main(String[] args) { Mat img = CvInvoke.Imread(@&quo ...
- 【转贴】使用sar进行性能分析
使用sar进行性能分析 https://www.cnblogs.com/bangerlee/articles/2545747.html 很早之前就看过 但是自己一直没用过.. 2012-06-12 0 ...
- HDU1305 Immediate Decodability (字典树
Immediate Decodability An encoding of a set of symbols is said to be immediately decodable if no cod ...
- HDU 4292 Food (建图思维 + 最大流)
(点击此处查看原题) 题目分析 题意:某个餐馆出售f种食物,d种饮料,其中,第i种食物有fi份,第i种饮料有di份:此时有n个人来餐馆吃饭,这n个人必须有一份食物和一份饮料才会留下来吃饭,否则,他将离 ...
- HDU 3416 Marriage Match IV (最短路建图+最大流)
(点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...
- unittest之一框架、suite
1.unittest是Python的标准库里的模块,所以在创建测试方法时,需直接导入unittest即可 2.unittest框架的六大模块: 测试用例TestCase 测试套件TestSuit:测试 ...
- 剑指offer-和为S的两个数字-知识迁移能力-python
题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述: 对应每个测试案例,输出两个数,小的先输出. 思路 ...
- django自带登录认证与登录自动跳转
# 导入django自带模块 from django.contrib.auth import authenticate, login, logout # 使用authenticate进行认证,使用lo ...