[ARC066F]Contest with Drinks Hard
来源:互联网 发布:日语扫描翻译软件 编辑:程序博客网 时间:2024/06/07 00:42
Description
给出一个序列a,你需要求出一个0/1序列c,使得
最大
给出m次修改形如(x,y),表示把a[x]改成y,每次修改之间独立,对于每次修改之后求出答案
n,m<=3*1e5
Solution
首先一次询问可以直接Dp
设Fi表示考虑到i的最大价值,O(n)转移显然
发现转移可以斜率优化,不过这个斜率优化写的是单调栈,自己感受一下
正着做一遍再反着做一遍,接下来我们只需要求出hi表示i必须选的答案
这个东西可以用cdq分治做,为了保证覆盖所有情况要正着做一遍再反着做一遍
注意分治边界的一些奇怪东西
Code
#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;typedef double db;int read() { char ch; for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); int x=ch-'0'; for(ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; return x;}const int N=3*1e5+5;const ll inf=1e16;int n,m,x,y,a[N],stack[N],top;ll f[N],g[N],h[N],ans[N],t[N],c[N],tmp[N],sum[N];db P(int y,int x) { return (t[y]+(ll)y*(y-1)/2+sum[y]-t[x]-(ll)x*(x-1)/2-sum[x])*1.0/(y-x);}void Dp() { fo(i,1,n) sum[i]=sum[i-1]+a[i];stack[top=1]=0; fo(i,1,n) { while (top>1&&P(stack[top],stack[top-1])<=i) top--; int now=stack[top]; t[i]=max(t[i-1],t[now]+(ll)(i-now)*(i-now+1)/2+sum[now]-sum[i]); while (top>1&&P(stack[top],stack[top-1])<P(i,stack[top])) top--; stack[++top]=i; }}void solve(int l,int r) { if (l==r) { h[l]=max(h[l],g[r+1]+f[l-1]+1-a[l]); return; } int mid=l+r>>1; stack[top=1]=l-1; fo(i,l,mid-1) { while (top>1&&P(stack[top],stack[top-1])<P(i,stack[top])) top--; stack[++top]=i; } fo(i,mid,r) { while (top>1&&P(stack[top],stack[top-1])<=i) top--; int now=stack[top]; tmp[i]=t[now]+(ll)(i-now)*(i-now+1)/2+sum[now]-sum[i]+g[i+1]; } fd(i,r-1,mid) tmp[i]=max(tmp[i],tmp[i+1]); fo(i,mid,r) h[i]=max(h[i],tmp[i]); solve(l,mid);solve(mid+1,r);}int main() { freopen("genocide.in","r",stdin); freopen("genocide.out","w",stdout); n=read(); fo(i,1,n) a[i]=read(); Dp();fo(i,1,n) f[i]=t[i]; fo(i,1,n/2) swap(a[i],a[n-i+1]); Dp();fo(i,1,n) g[i]=t[n-i+1]; fo(i,1,n) ans[i]=-inf; fo(i,1,n/2) swap(a[i],a[n-i+1]); fo(i,1,n) t[i]=f[i]; fo(i,1,n) sum[i]=sum[i-1]+a[i]; fo(i,1,n) h[i]=-inf; solve(1,n); fo(i,1,n) ans[i]=max(ans[i],h[i]); fo(i,1,n) swap(f[i],g[i]); fo(i,1,n/2) { swap(a[i],a[n-i+1]); swap(f[i],f[n-i+1]); swap(g[i],g[n-i+1]); } fo(i,1,n) t[i]=f[i]; fo(i,1,n) sum[i]=sum[i-1]+a[i]; fo(i,1,n) h[i]=-inf; solve(1,n); fo(i,1,n) ans[i]=max(ans[i],h[n-i+1]); fo(i,1,n/2) { swap(f[i],f[n-i+1]); swap(g[i],g[n-i+1]); swap(a[i],a[n-i+1]); } fo(i,1,n) swap(f[i],g[i]); for(m=read();m;m--) x=read(),y=read(),printf("%lld\n",max(f[x-1]+g[x+1],ans[x]+a[x]-y)); return 0;}
阅读全文
0 0
- [ARC066F]Contest with Drinks Hard
- [arc066f]Contest with Drinks Hard
- 【AtCoder Regular Contest 066 F】【JZOJ 5451】Contest with Drinks Hard
- Drinks
- AtCoder Grand Contest 001 EBBQ Hard
- B. Drinks
- Drinks Watermelon
- Codeforces Drinks
- Multithreaded unit testing with ConTest
- 2010 Asia Fuzhou Regional Contest 之 A hard Aoshu Problem
- 2017 Multi-University Training Contest 7:Hard challenge
- hard fault with Cortex M1 Rate Topic:
- CodeForces 200B Drinks
- CodeForces 200B Drinks
- Codeforces-200B-Drinks
- in Turkish drinks
- hard
- [Leetcode 30, Hard] Substring with Concatenation of All Words
- CSdn测试
- PyTorch笔记5-save和load神经网络
- 作业帮-将json数组里面的每一个对象的value取出生成与之对应的二维数组
- 串口 SWD Jtag
- 约瑟夫环(约瑟夫问题) 采用循环单链表实现
- [ARC066F]Contest with Drinks Hard
- JavaWeb开发模式一:JSP+JavaBean
- python3.5调用face++
- on、where、having的区别
- Java并发编程:Lock
- 静态链接库vs动态链接库
- Docker部署区块链
- 机器学习学习笔记:决策树归纳算法(ID3)
- PAT (Advanced Level) Practise