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 ...
随机推荐
- springcloud生态图
springcloud生态图
- Trie(字典树,前缀树)_模板
Trie Trie,又经常叫前缀树,字典树等等. Trie,又称前缀树或字典树,用于保存关联数组,其中的键通常是字符串.与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定.一个节点的 ...
- 仿制用友U8界面
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- centOS下更新yum源
CentOS下更新yum源 1.使用如下命令,备份/etc/yum.repos.d/CentOS-Base.repo. cp /etc/yum.repos.d/CentOS-Base.repo /et ...
- ruby 可枚举模块Enumerable
Enumerable模块提供了遍历,搜索,比较,排序等方法.如果我们自定义的类需要实现这些方法,必须实现一个each方法.如果需要使用max,min,sort等方法,因为这些方法是集合的元素之间的排序 ...
- Windows Server 2012下手动配置IIS的文件夹访问权限
当新建一个website的时候,一般情况下IIS对相应的物理文件夹的访问权限是不够的. 针对匿名认证(anonymous authentication)需要: 打开文件夹properties-> ...
- set<pair<int,int> > 的运用
In this cafeteria, the N tables are all ordered in one line, where table number 1 is the closest to ...
- NB-IOT的键值对
1. 关于NB-IOT的软件开发,有一个功能,NB收到数据的时候可以唤醒处于低功耗下的MCU. 2. 2个键值对可以配置这个功能.使用键值对的方式. 3. 遇到的第一个问题,<config> ...
- 【数据库】 SQL SERVER 2014 实用新特性
[数据库] SQL SERVER 2014 实用新特性 官方链接 一. 内存优化表 大幅提高数据库性能,不过目前没有窗口化设计只能写语句 二. 索引增强
- ubuntu自带的ibus输入法问题解决方法
ubuntu自带的ibus有点问题,输入字的时候不知道是个什么模式. 在网上搜到一个解决方法. 终端下执行: ibus-daemon -drx 然后切换到拼音输入法,就正常了. 写下作为记录.