LINK:holiday

考虑第一个subtask.

容易想到n^2暴力枚举之后再暴力计算答案.

第二个subtask 暴力枚举终点可以利用主席树快速统计答案.

第三个subtask 暴力枚举两端利用主席树计算贡献。

最后一个 subtask.

容易想到还是固定左端点来不断的寻找右端点。

不过很遗憾这最多只能做到\(n^2logn\)

需要从其他的角度入手 感觉前面几个subtask一直在迷惑选手。

可以从天数下手 左边多少天右边多少天。

显然 需要预处理出\(f1_i,f2_i\)分别表示从起点向右走i天能获得的最大价值,向右并且回到起点的最大价值.

左边同理.

答案利用这两个数字进行拼接即可。

值得注意的是 起点只能分给左右两边的一个并判断好边界问题。

然后就是求f数组了 容易想到枚举决策+贡献。

可以发现这是具有决策单调性的。证明不需要四边形不等式 下面我口胡一个。

假设有\(i,j,p\)其中\(p\)是\(j\)的最优决策 且\(i<j\) 那么对于i的最优决策一定\(<=p\)

反证法:若i的最优决策\(k>p\) 那么\(j\)也可以用\(k\)这个决策 i可以用\(p\)这个决策 把i在p这个决策时候用到的点和 在k用到的点标记。

可以发现k用到的点的和大于i用到的点的和 j也用k的话 由于j在p是包含i在p的选择 所以j也可以变成i \(p->k\)的样子 且其他东西不变 可以发现这样会更优。

所以j的最优决策会是k而不是p 与原命题相悖 所以假设成立。

总复杂度\(n\cdot log^2n\)

code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 10000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-4
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define V vector<int>
#define l(x) t[x].l
#define r(x) t[x].r
#define sum(x) t[x].sum
#define cnt(x) t[x].cnt
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=100010,maxn=300010;
int n,m,s1,op,ans,top,id;
int a[MAXN],b[MAXN],root[MAXN];
ll sum[MAXN];
ll f1[maxn];//从原点出发向右走的最大值.
ll f2[maxn];//从原点出发向右走之后走回起点的最大值.
ll f3[maxn];//从原点出发向左走的最大值.
ll f4[maxn];//从原点出发向左走之后走回起点的最大值.
struct wy
{
int l,r;
ll sum;
int cnt;
}t[MAXN*20];
inline void discrete()
{
sort(a+1,a+1+n);
rep(1,n,i)if(i==1||a[i]!=a[i-1])a[++top]=a[i];
rep(1,n,i)b[i]=lower_bound(a+1,a+1+top,b[i])-a;
}
inline void insert(int las,int &p,int l,int r,int x)
{
p=++id;t[p]=t[las];
sum(p)+=a[x];++cnt(p);
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)insert(l(las),l(p),l,mid,x);
else insert(r(las),r(p),mid+1,r,x);
}
inline ll ask(int x,int y,int l,int r,int k)
{
if(l==r)return (ll)k*a[l];
int mid=(l+r)>>1;
if(cnt(r(x))-cnt(r(y))>=k)return ask(r(x),r(y),mid+1,r,k);
return ask(l(x),l(y),l,mid,k-cnt(r(x))+cnt(r(y)))+sum(r(x))-sum(r(y));
}
inline ll ask(int l,int r,int k)
{
//求区间l~r的前k大的和.
ans=0;
if(k>=r-l+1)return sum[r]-sum[l-1];
return ask(root[r],root[l-1],1,top,k);
}
inline void solve1(int l,int r,int L,int R)
{
int mid=(l+r)>>1;int p=L,res;
rep(L,R,j)
{
res=mid-op*(j-s1);
if(res<=0)continue;
ll cc=ask(s1,j,res);
if(cc>f1[mid])
{
f1[mid]=cc;
p=j;
}
}
if(l<mid)solve1(l,mid-1,L,p);
if(r>mid)solve1(mid+1,r,p,R);
}
inline void solve2(int l,int r,int L,int R)
{
int mid=(l+r)>>1;int p=L,res;
rep(L,R,j)
{
res=mid-op*(j-s1);
if(res<=0)continue;
ll cc=ask(s1,j,res);
if(cc>f2[mid])
{
f2[mid]=cc;
p=j;
}
}
if(l<mid)solve2(l,mid-1,L,p);
if(r>mid)solve2(mid+1,r,p,R);
}
inline void solve3(int l,int r,int L,int R)
{
int mid=(l+r)>>1;int p=L,res;
fep(L,R,j)
{
res=mid-op*(s1-j);
if(res<=0)continue;
ll cc=ask(j,s1-1,res);
if(cc>f3[mid])
{
f3[mid]=cc;
p=j;
}
}
if(l<mid)solve3(l,mid-1,L,p);
if(r>mid)solve3(mid+1,r,p,R);
}
inline void solve4(int l,int r,int L,int R)
{
int mid=(l+r)>>1;int p=L,res;
fep(L,R,j)
{
res=mid-op*(s1-j);
if(res<=0)continue;
ll cc=ask(j,s1-1,res);
if(cc>f4[mid])
{
f4[mid]=cc;
p=j;
}
}
if(l<mid)solve4(l,mid-1,L,p);
if(r>mid)solve4(mid+1,r,p,R);
}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(s1)+1;get(m);
rep(1,n,i)b[i]=get(a[i]),sum[i]=sum[i-1]+a[i];
discrete();
rep(1,n,i)insert(root[i-1],root[i],1,top,b[i]);
op=1;solve1(1,m,s1,n);//规定右边带起点.
op=2;solve2(1,m,s1,n);
op=1;if(s1-1>=1)solve3(1,m,s1-1,1);
op=2;if(s1-1>=1)solve4(1,m,s1-1,1);
ll ans=0;rep(0,m,i)ans=max(ans,max(f1[i]+f4[m-i],f2[i]+f3[m-i]));
putl(ans);return 0;
}

luogu P5892 [IOI2014]holiday 假期 决策单调性优化dp 主席树的更多相关文章

  1. 洛谷 P5897 - [IOI2013]wombats(决策单调性优化 dp+线段树分块)

    题面传送门 首先注意到这次行数与列数不同阶,列数只有 \(200\),而行数高达 \(5000\),因此可以考虑以行为下标建线段树,线段树上每个区间 \([l,r]\) 开一个 \(200\times ...

  2. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  3. CF868F Yet Another Minimization Problem 分治决策单调性优化DP

    题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...

  4. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  5. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  6. BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】

    Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...

  7. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  8. 算法学习——决策单调性优化DP

    update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...

  9. BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】

    Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...

随机推荐

  1. css实现内容渐变隐藏效果,手机网页版知乎内容隐藏效果的实现

    看到一个需求,如下图,知乎手机网页版的一个视觉效果,对内容很长的部分有一个渐变的隐藏的效果,个人觉得这个设计还是很好的,符合手机大小的应用场景,没有一下子显示完全,可以很快的滑倒页面底部,一定程度上减 ...

  2. ASP.NET基础温习

  3. 一篇夯实一个知识点系列--python装饰器

    写在前面 本系列目的:希望可以通过一篇文章,不望鞭辟入里,但求在工程应用中得心应手. 装饰器模式是鼎鼎大名的23种设计模式之一.装饰器模式可以在不改变原有代码结构的情况下,扩展代码功能. Python ...

  4. 01 flask源码剖析之werkzurg 了解wsgi

    01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...

  5. Django框架06 /orm多表操作

    Django框架06 /orm多表操作 目录 Django框架06 /orm多表操作 1. admin相关操作 2. 创建模型 3. 增加 4. 删除 5. 修改 6. 基于对象的跨表查询 7. 基于 ...

  6. Go包管理go mod使用

    Go Modules介绍 为了解决Go包管理的问题,Go从1.11开始加入了Go Modules这一新特性.让包的依赖和版本管理更加容易. 一个module可以理解为一个单独的包或者模块,module ...

  7. java 正则提取字符串中的电话号码

    public static void test2() { String str = "张三:13539558064,李四:15626829748,赵六:13718952204"; ...

  8. 阅读手札 | 手把手带你探索『图解 HTTP』

    前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 Github 博客 学习清单: 一.网络基础 TCP/IP 通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上 ...

  9. Ethical Hacking - NETWORK PENETRATION TESTING(9)

    WEP Cracking Packet Injection What if the AP was idle, or had no clients associated with it? In this ...

  10. wordpress学习笔记

    版本:4.9.8 我用wordpress的初衷是借用它的后台系统,前端用自己的网页显示存在wordpress数据库里的文章. wordpress本质上是个框架,技术栈:web-php-mysql. 初 ...