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. CentOS 7 Docker安装部署Go Web

    Docker 是一种容器技术,它部署简单,能很好的进行服务隔离,生成镜像,Push到镜像仓库,其他机器一键拉取部署. Docker分为社区版CE和企业版EE,社区版是免费提供给个人和小型团队使用,企业 ...

  2. CF833 A The Meaningless Game

    题干 Slastyona and her loyal dog Pushok are playing a meaningless game that is indeed very interesting ...

  3. postman-4-响应内容

    通过响应报文来检测接口的正确性:响应由正文,响应头和状态码组成 Pretty模式可以格式化JSON或XML响应报文,以便更容易查看.突出显示Pretry模式中的链接,点击它们, 可以通过链接URL在P ...

  4. 仿Neo4j里的知识图谱,利用d3+vue开发的一个网络拓扑图

    项目需要画一个类似知识图谱的节点关系图. 一开始用的是echart画的. 根据https://gallery.echartsjs.com/editor.html?c=xH1Rkt3hkb,成功画出简单 ...

  5. java IO流 (八) RandomAccessFile的使用

    1.随机存取文件流:RandomAccessFile 2.使用说明: * 1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutpu ...

  6. 数据可视化之DAX篇(二十七)半累加度量,在Power BI 中轻松处理

    https://zhuanlan.zhihu.com/p/96823622 ​开始半累加的计算之前,我们先看看什么是累加.半累加以及不可累加数据. 在含有大量行的数据表中,各种数据处理语言,包括DAX ...

  7. 转自fineui论坛:解决fineui框架开发中的Designer.aspx.cs丢失问题

    在开发的时候碰到个问题,本来好好的Edit.aspx  Edit.aspx.cs  Edit.Designer.aspx.cs编辑Edit.aspx然后保存,编译的时候 发现Edit.aspx.cs里 ...

  8. OSCP Learning Notes - Exploit(7)

    Pre-Exploit Password Attacks Tools: 1. ncrack Ncrack 0.6 ( http://ncrack.org )Usage: ncrack [Options ...

  9. Python Ethical Hacking - ARPSpoof_Detector

    ARPSPOOF_DETECTOR Watch value for gateway mac in the arp table Nice and simple, but will not detect ...

  10. MSSQL系列 (一):数据库的相关操作(增删改查)

    1.创建数据库 --创建数据库 create database stuDb on primary ( --表示属于primary文件组 name='stuDb', --逻辑名称 fileName='D ...