AtCoder Regular Contest 066 F Contest with Drinks Hard
题意:
你现在有n个题目可以做,第i个题目需要的时间为t[i],你要选择其中的若干题目去做.
不妨令choose[i]表示第i个题目做不做.
定义cost=∑(i<=n)∑(i<=j<=n)(∏(i<=k<=j)choose[k])−∑(i<=n)choose[i]×t[i]
有q个询问,每个询问给出两个数p,x表示询问假设把t[p]修改成x,当你任意指定choose[]的值时,最大的cost是多少.
首先不考虑询问,dp一遍,f[i]表示前i个题目获得的最大收益,f[i]=max(f[i-1],max{f[j]+(i-j)*(i-j+1)-sum[i]+sum[j]}),斜率优化,正反各做一边
考虑询问,p要么选要么不选,不选的话很好说,选的话我们需要求出必选p整个序列的最大收益。
分治,每次处理必选x(mid<=x<=r),且x所在选择区间左端点在(l,mid),右端点在(mid,r)的答案,先求出以每个点为右端点的答案,再做一遍后缀最大值,就能求出每个x的答案。
第一次见分治还能这么用
#include<bits/stdc++.h>
#define int long long
#define N 300005
#define rev reverse
using namespace std;
int n,t[N],st[N],top,m;
int y[N],sum[N],f1[N],f2[N];
void yu(int *f)
{
f[0]=0;top=0;st[++top]=0;
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+t[i];
for(int i=1;i<=n;i++)
{
f[i]=f[i-1];
while(top>1&&y[st[top]]-y[st[top-1]]<=2*i*(st[top]-st[top-1]))top--;
f[i]=max(f[i],f[st[top]]+(i-st[top])*(i-st[top]+1)/2-sum[i]+sum[st[top]]);
y[i]=i*i-i+2*f[i]+2*sum[i];
while(top>1&&(y[st[top]]-y[st[top-1]])*(i-st[top-1])<=(y[i]-y[st[top-1]])*(st[top]-st[top-1]))top--;
st[++top]=i;
}
}
int f[N],tmp[N];
void solve(int *f1,int *f2,int l,int r)
{
if(l==r){f[l]=max(f[l],f1[l-1]+f2[l+1]-t[l]+1);return ;}
int mid=(l+r)>>1;top=0;
for(int i=l-1;i<mid;i++)
{
y[i]=i*i-i+2*f1[i]+2*sum[i];
while(top>1&&(y[st[top]]-y[st[top-1]])*(i-st[top-1])<=(y[i]-y[st[top-1]])*(st[top]-st[top-1]))top--;
st[++top]=i;
}
for(int i=mid;i<=r;i++)
{
while(top>1&&y[st[top]]-y[st[top-1]]<=2*i*(st[top]-st[top-1]))top--;
tmp[i]=f2[i+1]+f1[st[top]]-sum[i]+sum[st[top]]+(i-st[top])*(i-st[top]+1)/2;
}
for(int i=r-1;i>=mid;i--)tmp[i]=max(tmp[i],tmp[i+1]);
for(int i=mid;i<=r;i++)f[i]=max(f[i],tmp[i]);
solve(f1,f2,l,mid);solve(f1,f2,mid+1,r);
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&t[i]); yu(f1);rev(t+1,t+n+1);
yu(f2);
rev(t+1,t+n+1);rev(f2+1,f2+n+1);
for(int i=1;i<=n;i++)f[i]=-t[i];
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+t[i];
solve(f1,f2,1,n); rev(t+1,t+n+1);rev(f+1,f+n+1);rev(f1+1,f1+n+1);rev(f2+1,f2+n+1);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+t[i];
solve(f2,f1,1,n);
rev(t+1,t+n+1);rev(f+1,f+n+1);rev(f2+1,f2+n+1);rev(f1+1,f1+n+1); scanf("%lld",&m);
for(int i=1;i<=m;i++)
{
int t1,t2;scanf("%lld%lld",&t1,&t2);
printf("%lld\n",max(f1[t1-1]+f2[t1+1],f[t1]-t2+t[t1]));
}
return 0;
}
AtCoder Regular Contest 066 F Contest with Drinks Hard的更多相关文章
- Atcoder Regular Contest 066 F genocide【JZOJ5451】
题目 分析 \(s[i]\)表示a前缀和. 设\(f[i]\)表示做完了1~i的友谊颗粒的最优值(不一定选i),那么转移方程为 \[f[i]=max\{f[i-1],max\{f[j]-s[i]+s[ ...
- AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图
AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
随机推荐
- iphone忘记锁屏密码却记得appleID密码的不保存数据的刷机办法
请注意看清题目再看本文,另外一切后果博主不负任何责任.操作实现环境:原装数据线,拔掉sim卡昨天,iPhone6sp忘记密码被锁定,尝试通过找回手机抹除手机功能后,提示需要手机接入互联网才能实现,而我 ...
- Notepad++列编辑
NotePad++列编辑 工具:Notepad++使用说明:在我们的日常工作中,经常会碰到要修改多行记录,一行行去处理会非常浪费人力,这时候列编辑就是一个很好的解决方法,列编辑在进行数据批量操作时是一 ...
- win8系统本地服务网络受限cpu占用率过高解决方案
今天更新软件时突然就打不开软件了,接着cpu就飙升. 打开任务管理器看到是“本地服务网络受限”这么一个东西占用的cpu最高. 在网上找到的解决方案无效的: 1.关闭家庭组(服务里的homegroup· ...
- mysql启动后随即关闭问题解决(ibdata1文件损坏导致)
机房一台服务器上的mysql运行一段时间了,突然出现了一个很奇怪的现象:重启后无法恢复了!准确情况是:启动mysql后随即就又关闭了. 查看mysql错误日志如下: 160920 22:41:41 m ...
- sigar开发(java)
下载sigar,地址:https://yunpan.cn/cBEWbEfdAm98f (提取码:f765) 可以收集的信息 CPU信息:包括基本信息(vendor.model.mhz.cacheSiz ...
- SQL多表查询总结
前言 连接查询包括合并.内连接.外连接和交叉连接,如果涉及多表查询,了解这些连接的特点很重要.只有真正了解它们之间的区别,才能正确使用. 一.Union UNION 操作符用于合并两个或多个 SELE ...
- ULMFiT 阅读笔记
ULMFiT 阅读笔记 概述 这篇文章从文本分类模型入手,主要提出了两点:一是预训练语言模型在大中小规模的数据集中都能提升分类效果,在小规模数据集中效果尤为显著.二是提出了多种预训练的调参方法,包括D ...
- Linux内核期中
Linux内核期中总结 一.计算机是如何工作的 个人理解:计算机就是通过和用户进行交互,执行用户的指令,这些指令存放在内存中,通过寄存器存储,堆栈变化,来一步步顺序执行. 二.存储程序计算机工作模型 ...
- charCodeAt与fromCharCode
charCodeAt() 方法可返回指定位置的字符的 Unicode 编码 这个返回值是 0 - 65535 之间的整数. stringObject.charCodeAt(index) /* a-z ...
- Linux大页内存管理等---菜鸟初学
1. 查看linux的内存情况: free -m 2. 查看是否开启大页的方法: cat /proc/meminfo |grep -i HugePage AnonHugePages: 276480 k ...