BZOJ4367 IOI2014holiday假期(整体二分+主席树)
显然最优策略是先走到一边要到达的最远城市,再换方向走到另一边要到达的最远城市(当然也可以直接停止),路上参观景点。
先仅考虑求出只向左走,花费时间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假期(整体二分+主席树)的更多相关文章
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
- 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】
题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...
- BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树
这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...
- 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组
[BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...
- BZOJ2653 middle 【二分 + 主席树】
题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...
- BZOJ 4009: [HNOI2015]接水果 (整体二分+扫描线 树状数组)
整体二分+扫描线 树状数组 具体做法看这里a CODE #include <cctype> #include <cstdio> #include <cstring> ...
- bzoj4009 [HNOI2015]接水果 整体二分+扫描线+树状数组+dfs序
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4009 题解 考虑怎样的情况就会有一个链覆盖另一个链. 设被覆盖的链为 \(a - b\),覆盖 ...
- [bzoj2653][middle] (二分 + 主席树)
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
随机推荐
- PHP将二位数组按照第二维的某个元素的值进行排序
例如: //原始数组是这样的,希望能够按照第二维中的run_date升序或者降序进行排序: $arr=array( 0=>array( 'run_date'=>'2017-11-21', ...
- 企业Shell面试题及企业运维实战案例(三)
1.企业Shell面试题1:批量生成随机字符文件名案例 使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下: ...
- Eclipse build时间太长,无法忍受,完美解决方案,Eclipse 编译太卡,耗时太长
目前开发使用了Eclipse ,每次报错的时候都会build,,每次build的时间都很长,接近10秒左右,好难受呀.. 刚开始一直以为是项目内容多导致的,但是想想之前做的项目,无论再多,也都是秒级的 ...
- [转]win7下修改C盘USERS文件下的名称
Win7下C:\Users\Cortana以账户名称命名的系统文件夹用户名的修改 Win7下C:\Users\Cortana以账户名称命名的系统文件夹用户名的修改 Win7下C:\Users\Co ...
- STM32F4使用FPU+DSP库进行FFT运算的测试过程二
原文地址:http://www.cnblogs.com/NickQ/p/8541156.html 测试环境:单片机:STM32F407ZGT6 IDE:Keil5.20.0.0 固件库版本:STM32 ...
- go web cookie和session
cookie是存储在浏览器端,session是服务器端 cookie是有时间限制的,分会话cookie和持久cookie,如果不设置时间,那周期就是创建到浏览器关闭为止.这种是会话cookie,一般保 ...
- RedHat安装Oracle后中文乱码
radhat7.1 Oracle11gr2 安装Oracle时忘记设置字符集,导致安装后中文乱码,中文变成"???????????" 分析原因是Oracle服务器端和客户端的字符集 ...
- Uber:中国市场两年内不考虑盈利,每年补贴10亿美金
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- autofac无法解析一例
在asp.net mvc分项目开发中,如果类库位于其他的项目中,则必须在global中对其他项目的类库进行注册,否则会报“ None of the constructors found with 'A ...
- sed 集合(项目中的笔记)
奇数行和偶数行合并为一行: Like: Sequence number: 5398Sequence name: Glyma.16G123500.1Sequence number: 5399Sequen ...