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

  先仅考虑求出只向左走,花费时间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. http状态码(status_codes)

    首先:1XX 接受的请求正在处理,2XX请求正常处理完毕,3XX需要进行附加操作以完成请求(重定向?),4XX服务器无法处理请求(也就是客户端请求错误),5XX服务器处理请求出错. 当然不仅仅是一张图 ...

  2. Apache Maven(四):依赖

    依赖管理是Maven的特性之一,它是用户最为熟悉的特性之一,也是Maven擅长的领域之一.管理单个项目的依赖并没有太大困难,但是当您开始处理由数十或数百个模块组成的多模块项目和应用程序时,Maven可 ...

  3. I/O流、ZIP文档

    1) ZIP文档通常以压缩格式存储一个或多个文档.在Java中可以用ZipInputStream读入ZIP文档(即解压文件流),用ZipOutputStream写入ZIP文档(即压缩文件流),无论解压 ...

  4. php 微信客服信息推送失败 微信重复推送客服消息 40001 45047

    /*** * 微信客服发送信息 * 微信客服信息推送失败 微信重复推送客服消息 40001 45047 * 递归提交到微信 直到提交成功 * @param $openid * @param int $ ...

  5. ECSHOP和SHOPEX快递单号查询中通插件V8.6专版

    发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...

  6. 微信小程序终于审核过了

    终于,我做的微信小程序审核结束了,虽然被退回来两次,但是第三次还是审核通过了! 加油骚年,相信自己!! 有什么问题可以评论告诉我!!

  7. 【JDBC】一、JDBC连接数据库

    package com.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLExce ...

  8. A*与IDA*的奇妙之旅

    因为A*卡了一天QAQ 那么,A*是什么呢? A* A*是对于bfs的优化,启发式搜索. 例如下图: 不错,在这张图上,小人去找电脑,用bfs的话: 黄色就是bfs的搜索范围...不要问我为什么选黄色 ...

  9. Eclipse报错:An internal error occurred during: "Building workspace". Java heap space),卡死解决办法

    在项目工程的根目录下,找到.project,用记事本打开,把两处删除掉: 第一处: <buildCommand> <name>org.eclipse.wst.jsdt.core ...

  10. 安装cloudera manager使用mysql作为元数据库

    1.首次安装好mysql数据库后,会生成一个随机密码,使用如下办法找到: cat /var/log/mysqld.log |grep password 2.首次安装好mysql数据库后,第一次登陆进去 ...