显然最优策略是先走到一边要到达的最远城市,再换方向走到另一边要到达的最远城市(当然也可以直接停止),路上参观景点。

  先仅考虑求出只向左走,花费时间i时的最优解。如果能求出这个,类似的就可以求出所有情况。

  显然时间越长,应该往左边走的越远,参观的越多,但是这个最远城市的变化不一定连续,没法愉快地双指针或者直接二分答案。

  考虑类似整体二分的做法。设当前要求i在l~r,最远城市在x~y之间的最优解,对i=mid暴力求出最优解,然后递归处理两边。暴力需要进行nlog次,每次暴力需要求区间k大和,可以用主席树做到log,于是复杂度O(nlog2n)。

  注意起点处只能取一次。并且对mid求出的最远点如果有多解考虑清楚选哪一个。

  upd:才想起来这玩意就是决策单调性

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 100010
#define ll long long
int n,start,m,a[N],b[N],root[N],cnt,t;
ll fl[N<<],gl[N<<],fr[N<<],gr[N<<];
struct data{int l,r,x;ll sum;
}tree[N*];
struct data2{ll x;int d;};
void ins(int &k,int l,int r,int x)
{
tree[++cnt]=tree[k],k=cnt;
tree[k].x++,tree[k].sum+=b[x];
if (l==r) return;
int mid=l+r>>;
if (x<=mid) ins(tree[k].l,l,mid,x);
else ins(tree[k].r,mid+,r,x);
}
ll query(int x,int y,int l,int r,int k)
{
if (!y) return ;
if (l==r) return 1ll*min(tree[y].x-tree[x].x,k)*b[l];
int mid=l+r>>,t=tree[tree[y].r].x-tree[tree[x].r].x;
if (t>=k) return query(tree[x].r,tree[y].r,mid+,r,k);
else return tree[tree[y].r].sum-tree[tree[x].r].sum+query(tree[x].l,tree[y].l,l,mid,k-t);
}
data2 calc(int tot,int x,int y,int op,int isr)
{
int mx=isr?x:y;ll ans=;
if (isr)
{
for (int i=x;i<=y;i++)
if (tot>=abs(start-i)*(+op))
{
ll v;
if (i<start) v=query(root[i-],root[start-op],,t,tot-(start-i)*(+op));
else v=query(root[start-+op],root[i],,t,tot-(i-start)*(+op));
if (v>ans) ans=v,mx=i;
}
}
else
{
for (int i=y;i>=x;i--)
if (tot>=abs(start-i)*(+op))
{
ll v;
if (i<start) v=query(root[i-],root[start-op],,t,tot-(start-i)*(+op));
else v=query(root[start-+op],root[i],,t,tot-(i-start)*(+op));
if (v>ans) ans=v,mx=i;
}
}
return (data2){ans,mx};
}
void solve1(int l,int r,int x,int y)
{
if (l>r||x>y) return;
int mid=l+r>>;data2 t=calc(mid,x,y,,);
fl[mid]=t.x;
solve1(l,mid-,t.d,y);
solve1(mid+,r,x,t.d);
}
void solve2(int l,int r,int x,int y)
{
if (l>r||x>y) return;
int mid=l+r>>;data2 t=calc(mid,x,y,,);
fr[mid]=t.x;
solve2(l,mid-,x,t.d);
solve2(mid+,r,t.d,y);
}
void solve3(int l,int r,int x,int y)
{
if (l>r||x>y) return;
int mid=l+r>>;data2 t=calc(mid,x,y,,);
gl[mid]=t.x;
solve3(l,mid-,t.d,y);
solve3(mid+,r,x,t.d);
}
void solve4(int l,int r,int x,int y)
{
if (l>r||x>y) return;
int mid=l+r>>;data2 t=calc(mid,x,y,,);
gr[mid]=t.x;
solve4(l,mid-,x,t.d);
solve4(mid+,r,t.d,y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4367.in","r",stdin);
freopen("bzoj4367.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),start=read()+,m=read();
for (int i=;i<=n;i++) b[i]=a[i]=read();
sort(b+,b+n+);
t=unique(b+,b+n+)-b-;
for (int i=;i<=n;i++) a[i]=lower_bound(b+,b+t+,a[i])-b;
for (int i=;i<=n;i++)
{
root[i]=root[i-];
ins(root[i],,t,a[i]);
}
solve1(,m,,start);
solve2(,m,start,n);
solve3(,m,,start-);
solve4(,m,start+,n);
ll ans=;
for (int i=;i<=m;i++)
ans=max(ans,gl[i]+fr[m-i]),
ans=max(ans,gr[i]+fl[m-i]);
cout<<ans;
return ;
}

BZOJ4367 IOI2014holiday假期(整体二分+主席树)的更多相关文章

  1. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  2. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

  3. BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  4. 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树

    这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...

  5. 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

    [BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...

  6. BZOJ2653 middle 【二分 + 主席树】

    题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...

  7. BZOJ 4009: [HNOI2015]接水果 (整体二分+扫描线 树状数组)

    整体二分+扫描线 树状数组 具体做法看这里a CODE #include <cctype> #include <cstdio> #include <cstring> ...

  8. bzoj4009 [HNOI2015]接水果 整体二分+扫描线+树状数组+dfs序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4009 题解 考虑怎样的情况就会有一个链覆盖另一个链. 设被覆盖的链为 \(a - b\),覆盖 ...

  9. [bzoj2653][middle] (二分 + 主席树)

    Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...

随机推荐

  1. 爬虫——正则表达式re模块

    为什么要学习正则表达式 实际上爬虫一共就四个主要步骤: 明确目标:需清楚目标网站 爬:将所有的目标网站的内容全部爬下来 取:在爬下来的网站内容中去掉对我们没有用处的数据,只留取我们需要的数据 处理数据 ...

  2. python实现简单决策树(信息增益)——基于周志华的西瓜书数据

    数据集如下: 色泽 根蒂 敲声 纹理 脐部 触感 好瓜 青绿 蜷缩 浊响 清晰 凹陷 硬滑 是 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 是 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 是 青绿 蜷缩 沉闷 清晰 ...

  3. idea中创建web项目搭建Hibernate框架连接oracle数据库

    hibernate框架 hibernate是数据化持久工具,也是一个开源代码的ORM解决方案.hibernate内部封装了通过jdbc访问数据库的操作,向商场应用提供面向对象的数据访问api. hib ...

  4. JQuery中使用FormData异步提交数据和提交文件

    web中数据提交事件是常常发生的,但是大多数情况下我们不希望使用html中的form表单提交,因为form表单提交会中断当前浏览器的操作并且会调到另一个地址(即使这个地址是当前页面),并且会重复加载一 ...

  5. js中的逻辑与和逻辑或随笔

    逻辑与:&&,都真才真 逻辑或:||,一真都真 逻辑运算两侧不都是布尔值时,会隐式转换为布尔值转换规则:转换为true:非0数字(包含infinity).非空字符串转换为false:0 ...

  6. python应用:TXT文件的读写

    python读写TXT文件不需要导入包 python中常用的读写方式: 文件打开模式 描述 r 以只读模式打开文件,并将文件指针指向文件头:如果文件不存在会报错 w 以只写模式打开文件,并将文件指针指 ...

  7. Java学习笔记四:Java的八种基本数据类型

    Java的八种基本数据类型 Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. Java基本类型共有八种,基本类型可以分为三类,字符类型char,布 ...

  8. Vijos 纸牌

    题目网址 https://vijos.org/d/Randle/p/5a0011e1d3d8a10a532d6d71 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真 ...

  9. 博科brocade光纤交换机alias-zone的划分-->实操案例

    一,图形化操作 光纤交换机作为SAN网络的重要组成部分,在日常应用中非常普遍,本次将以常用的博科交换机介绍基本的配置方法. 博科300实物图: 环境描述: 如上图,四台服务器通过各自的双HBA卡连接至 ...

  10. MVC中Model 的Key值不建议用非int型

    一次在开发中,key的值用了 byte型,结果插入第一条正常,第二条开始就出错,原因是用byte类型无法实现自动增加1,所以为了方便,建议使用 int型. public virtual byte bk ...