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. 介绍web开发中实现会话跟踪的常用技术方法

    由于http是无状态的协议,这种特性严重阻碍了客户端与服务器进行动态交互,例如购物车程序,客户在购物车中添加了商品,服务器如何知道购物车已有的物品呢?为了支持客户端与服务器之间的交互,为了弥补http ...

  2. CF819B Mister B and PR Shifts 思维题

    分析 这道题\(n\leq10^{6}\),显然\(n^{2}\)的暴力是无法解决问题的 那么我们可以考虑数列的某一种性质 因为最终的答案是\(\sum{n \atop i=1} |p_i - i|\ ...

  3. Git篇--将代码上传到git完整版

    1.注册github账号. 2.创建个人的github仓库,如图,   或者也可以进入个人中心去创建,   还可以直接点击右上角的“”+“”添加, 3.创建自己的Repository,如图: 4.新建 ...

  4. 代码注入——c++代码注入

    代码注入之——c++代码注入 0x00  代码注入和DLL注入的区别 DLL注入后DLL会通过线程常驻在某个process中,而代码注入完成之后立即消失. 代码注入体积小,不占内存 0x01  通过c ...

  5. Yii2源码分析(一):入口

    写在前面,写这些随笔是记录下自己看Yii2源码的过程,可能会有些流水账,大部分解析放在注释里说明,由于个人水平有限,有不正确的地方还望斧正. web入口文件Index.php // 定义全局的常量,Y ...

  6. Mysql基础(十一):流程控制结构、分支结构、循环结构

    流程控制结构 说明:顺序结构:程序从上往下依次执行分支结构:程序按条件进行选择执行,从两条或多条路径中选择一条执行循环结构:程序满足一定条件下,重复执行一组语句 分支结构 特点:1.if函数功能:实现 ...

  7. 数据可视化之powerBI技巧(一)PowerBI可视化技巧:KPI指标动态展示之TOPN及其他

    ​本文来自星友Beau的分享,在进行数据指标的展现时,对关键的少数单独展示,而对剩余的大多数折叠为其他项,是一个很常用的做法.Beau同学通过一个日常的办公场景,详细介绍了PowerBI实现的步骤,值 ...

  8. Unity3D+Post Processing Stack V2自定义后处理效果研究

    背景 众所周知,Unity3D支持自定义后处理效果,实现过程有三步: 添加着色器,在着色器里书写后处理代码: 添加材质,把材质和着色器绑定: 给相机添加脚本,重写其OnRenderImage方法,将材 ...

  9. 区分C语言中的指针函数和函数指针

    1.指针函数: 类型说明符 *函数名(形参表) { ..........   /*函数体*/ ..........    /*函数体*/ } 其中函数名之前加了"*"号表明,这是一 ...

  10. Istio安全-认证(istio 系列七)

    Istio安全-认证 目录 Istio安全-认证 认证策略 配置 自动mutual TLS 全局启用istio的mutual TLS STRIC模式 卸载 针对单个命名空间或负载启用mutual TL ...