传送门

题目大意

有一个长为$N$的序列$A$,你要构造一个长为$N$的$01$序列使得$01$序列全部由$1$组成的子串个数$-$两个序列的对应位置两两乘积之和最大,每次独立的询问给定$pos,x$,求当$A_{pos}=x$时最大的答案,每次询问后将$A$复原。

题解

考虑不加入询问单纯地求原序列最大价值就变成了经典的斜率优化。

设$S$为序列$A$的前缀和,$F_i$表示对于前$i$个位置其中第$i$个不选的最大价值,假设枚举$j$表示上一个不选的位置是$j$。

那么$F_i=F_j-(S_{i-1}-S_j)+\frac{(i-j-1)(i-j)}{2}$。

这个式子可以优化,只需要维护$(j,F_j+S_j+\frac{j(j+1)}{2})$的上凸壳即可。

不难发现斜率$i$是递增的,所以具有决策单调性,用单调栈维护即可,可以做到$O(n)$。

现在加入了限制将$A_{pos}$改为$x$,发现只有两种情况。

第一种,不选$A_{pos}$,那么只需要预处理出前缀和后缀的$Dp$值$F$和$G$,那么答案就是$F_{pos}+G_{pos}$。

第二种,选了$A_{pos}$,那么要满足选了某个区间$[l,r]$其中$l\leq pos\leq r$。

考虑预处理出$H_i$表示强制选第$i$个的答案,那么答案就是$H_i+A_{pos}-x$,我们现在只需要求出$H_i$即可。

直接枚举跨越$i$的区间比较难办,考虑分治,每个分治区$[l,r]$只讨论选了上一个不选的$\in[l-1,mid]$,最后一个选的$\in[mid+1,r]$的答案,以及后缀意义下上一个不选的$\in[mid+1,r+1]$,最后一个选的$\in[l,mid]$的答案。

每次分别求出了了一定覆盖$x(x\in[l,mid])$的答案和一定覆盖$y(y\in[mid+1,r])$,求出$x$的前缀最大值和$y$的后缀最大值,分别用于更新覆盖$x$的更新$y$的答案。

复杂度$O(N\log N+Q)$

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define INF 10000000000000ll
#define M 300020
using namespace std;
namespace IO{
const int BS=(1<<20)+5; int Top=0;
char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
void flush(){fwrite(OT,1,OS-OT,stdout);}
void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
void write(LL x){
if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
while(x) SS[++Top]=x%10,x/=10;
while(Top) Putchar(SS[Top]+'0'),--Top;
}
int read(){
int nm=0,fh=1; char cw=Getchar();
for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
}
using namespace IO;
int n,m,p[M];
LL H[M],G[M],F[M],S[M],top,D[M],P[M];
LL X[M],Y[M];
#define calc(b,a) x[b]-S[a-1]+S[b]+((LL)(a-b-1)*(LL)(a-b)>>1)
#define conv(a,b,c) ((double)(Y[b]-Y[a])/(double)(X[b]-X[a])>(double)(Y[c]-Y[b])/(double)(X[c]-X[b]))
#define Transl(b,a) G[a+1]-S[a]+S[b]+F[b]+((LL)(a-b)*(LL)(a-b+1)>>1)
#define Transr(b,a) F[a-1]-S[a]+S[b]+G[b]+((LL)(b-a)*(LL)(b-a+1)>>1)
void init(LL *x){
S[top=1]=0,Y[0]=X[0]=S[0]=0;
for(LL i=1;i<=n+1;i++) S[i]=S[i-1]+p[i];
for(LL i=0;i<=n+1;i++){
while(top>1&&calc(P[top-1],i)>=calc(P[top],i)) top--;
if(top) x[i]=calc(P[top],i);else x[i]=0;
X[i]=i,Y[i]=x[i]+S[i]+((i*i+i)>>1);
while(top>1&&!conv(P[top-1],P[top],i)) top--; P[++top]=i;
}
}
void solve(int l,int r){
if(l==r){H[l]=max(H[l],F[l-1]+G[r+1]-p[l]+1);return;}
int mid=((l+r)>>1); solve(l,mid),solve(mid+1,r);
top=S[l-1]=S[r+1]=X[l-1]=X[r+1]=Y[l-1]=Y[r+1]=0;
D[l-1]=D[r+1]=-INF; top=0; for(int i=l;i<=r;i++) D[i]=-INF,S[i]=S[i-1]+p[i]; top=0;
for(int i=l-1;i<=mid;i++){
X[i]=i,Y[i]=F[i]+S[i]+(((LL)i*(LL)i+(LL)i)>>1);
while(top>1&&!conv(P[top-1],P[top],i)) top--; P[++top]=i;
}
for(int i=mid+1;i<=r;i++){
while(top>1&&Transl(P[top-1],i)>=Transl(P[top],i)) top--;
D[i]=Transl(P[top],i);
}
for(int i=r;i>mid;i--) D[i]=max(D[i+1],D[i]),H[i]=max(H[i],D[i]); for(int i=r;i>=l;i--) S[i]=S[i+1]+p[i]; top=0;
for(int i=r+1;i>mid;i--){
X[i]=i,Y[i]=G[i]+S[i]+(((LL)i*(LL)i+(LL)i)>>1);
while(top>1&&!conv(i,P[top],P[top-1])) top--; P[++top]=i;
}
for(int i=mid;i>=l;i--){
while(top>1&&Transr(P[top-1],i)>=Transr(P[top],i)) top--;
D[i]=Transr(P[top],i);
}
for(int i=l;i<=mid;i++) D[i]=max(D[i-1],D[i]),H[i]=max(H[i],D[i]);
}
int main(){
n=read(); for(int i=1;i<=n;i++) p[i]=read(),H[i]=-INF;
init(F),reverse(p+1,p+n+1),init(G),reverse(p+1,p+n+1);
reverse(G+1,G+n+1),G[0]=G[n+1],G[n+1]=0; solve(1,n);
for(int TT=read();TT;TT--,Putchar('\n')){
LL pos=read(),K=read();
write(max(F[pos]+G[pos],H[pos]+p[pos]-K));
} flush(); return 0;
}

Arc066_F Contest with Drinks Hard的更多相关文章

  1. Contest with Drinks Easy

    /* Problem Statement Joisino is about to compete in the final round of a certain programming competi ...

  2. [arc066f]Contest with Drinks Hard

    题目大意: 有一些物品,每个买了有代价. 如果存在一个极大区间[l,r]内的物品都被买了,这个区间长度为k,可以获得的收益是k*(k+1)/2. 现在若干次询问,每次问假如修改了某个物品的价格,最大收 ...

  3. AtCoder Regular Contest 066 F Contest with Drinks Hard

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

  4. 【ARC066】F - Contest with Drinks Hard

    题解 我写的斜率维护,放弃了我最擅长的叉积维护,然后发现叉积维护也不会爆long long哦-- 一写斜率维护我的代码就会莫名变长而且难写--行吧 我们看这题 推了推式子,发现这是个斜率的式子,但是斜 ...

  5. @atcoder - ARC066F@ Contest with Drinks Hard

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定序列 T1, T2, ... TN,你可以从中选择一些 Ti ...

  6. [atARC066F]Contest with Drinks Hard

    先不考虑修改,那么很明显即对于每一个极长的的区间,若其长度为$l$,有${l+1\choose 2}$的贡献 考虑dp去做,即$f_{i}$表示前$i$个数最大的答案,则$$f_{i}=\max(\m ...

  7. AT2274 [ARC066D] Contest with Drinks Hard

    先考虑不修改怎么做,可以令 \(dp_i\) 表示前 \(i\) 个题能获得的最大得分.那么我们有转移: \[dp_i = \min\{dp_{i - 1}, dp_{j} + \frac{(i - ...

  8. AtCoder Beginner Contest 050 ABC题

    A - Addition and Subtraction Easy Time limit : 2sec / Memory limit : 256MB Score : 100 points Proble ...

  9. 【AtCoder】ARC066

    ARC066 C - Lining Up 判断是否合法即可,合法是\(2^{\lfloor \frac{N}{2}\rfloor}\) 不合法就是0 #include <bits/stdc++. ...

随机推荐

  1. Django 项目补充知识(JSONP,前端瀑布流布局,组合搜索,多级评论)

    一.JSONP 1浏览器同源策略 通过Ajax,如果在当前域名去访问其他域名时,浏览器会出现同源策略,从而阻止请求的返回 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一 ...

  2. loadrunder之脚本篇——定义全局变量

    如果参数是全局的,在脚本中的任何一个Action中都可以使用,变量一般是局部的,如果跨Action调用会出现未声明的错误. 打开Script视图中左侧Action列表中的globals.h文件,可定义 ...

  3. 树莓派从 DHT11 温度湿度传感器读取数据

    时序图参考厂家说明书:DHT11数字湿温度传感器的原理和应用范例 四个阵脚连接:VCC接3.3伏电源,Dout接GPIO口,我接的是物理12针脚,NC留空,GND接地. 波折1:电阻被错接进了VCC, ...

  4. python + Streaming框架的MR实践与优化

    Streaming是Hadoop提供的一个可以使用其他编程语言来进行MR编程的API,它使用Unix标准输入输出作为Hadoop和其他编程语言的开发接口,非常轻便.而开发者可以选择自己擅长的编程语言, ...

  5. 【收藏】SearchCrawler By James Holmes

    转自Crawling the Web with Java By James Holmes 无需任何扩展包,可直接运行. import java.awt.*; import java.awt.event ...

  6. P4755 Beautiful Pair

    题目 洛谷 做法 \(i≤x≤j,a[i]<\frac{a[x]}{a[j]}\) 考虑\(a[x]\)的贡献,单调栈预处理\(L,R\)能作为最大值的区间 枚举一端点,仅需另一端点满足条件即可 ...

  7. 20145231《Java程序设计》第二次实验报告

    实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD: 理解并掌握面向对象三要素: 初步掌握UML建模: 熟悉S.O.L.I.D原则: 了解设计模式: 实验要求 实现并体会例子中代码的 ...

  8. git上面创建个人简历-链接

    github创建个人在线简历: https://segmentfault.com/a/1190000006820290

  9. Python 字典Dict概念和操作

    # 字典概念:无序的, 可变的键值对集合 # 定义 # 方式1 # {key: value, key: value...} # 例如 # {"name": "xin&qu ...

  10. ssh框架整合意义

    一次次学习,一次次不一样的进一步理解. 一.Struts2.String.Hibernate框架的整合的意义: 1.需要将所有的对象进行统一管理(action动作类:sessionFactory) 2 ...