[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
试题描述
输入
见“试题描述”
输出
见“试题描述”
输入示例
见“试题描述”
输出示例
见“试题描述”
数据规模及约定
见“试题描述”
题解
最优解一定是在一段连续的包含 \(0\) 号点的区间中选择最小的 \(k\) 个印花,其中一边需要折返(即代价为两倍距离)。
所以我们先将一边的距离 \(\times 2\),然后两边分别求出 \(f_k\) 表示印 \(k\) 个花至少需要花费的代价,最后枚举一边的答案,并通过剩余步数二分得到另一边的答案即可。
考虑一边的 \(f_k\) 如何处理,这个方案其实就是确定一个点 \(u\),然后印 \(0\) 到 \(u\) 之间的最小的 \(k\) 个花,不难发现随着 \(k\) 增加,\(u\) 也是单调移动的。由于不好确定最优解具体在哪,我们考虑分治解决这个问题,令 \(solve(l, r, ql, qr)\) 表示答案在区间 \([l, r]\) 中,询问区间为 \([ql, qr]\),这个时候我们询问一下 \([ql, qr]\) 的中点(这个询问就是暴力扫一遍 \([l, r]\) 然后再数据结构查询一下前 \(k\) 小的总和,找到最优的位置 \(p\),下次左半部分的询问归到 \([l, p]\) 中,右半部分归到 \([p, r]\) 中),然后继续递归下去就好了。我们需要一个数据结构支持查询区间内前 \(k\) 小的数之和,主席树就可以实现。
最后总复杂度是 \(O(n \log^2 n)\),那个分治是 \(O(n \log n)\) 的,因为每层最多询问 \(O(n)\) 次,有 \(\log n\) 层。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)
#define LL long long
LL read() {
LL x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 100010
#define maxnode 2000010
#define ool (1ll << 60)
#define pli pair <LL, int>
#define x first
#define y second
#define mp(x, y) make_pair(x, y)
int n, dis[maxn], Time[maxn], num[maxn];
LL lim;
pli Info[maxn];
LL sumv[maxnode];
int ToT, rt[maxn], lc[maxnode], rc[maxnode], siz[maxnode];
void update(int& y, int x, int l, int r, int p) {
sumv[y = ++ToT] = sumv[x] + num[p];
siz[y] = siz[x] + 1;
if(l == r) return ;
int mid = l + r >> 1; lc[y] = lc[x]; rc[y] = rc[x];
if(p <= mid) update(lc[y], lc[x], l, mid, p);
else update(rc[y], rc[x], mid + 1, r, p);
return ;
}
LL query(int o, int l, int r, int k) {
if(!o) return 0;
if(siz[o] == k) return sumv[o];
int mid = l + r >> 1;
if(k <= siz[lc[o]]) return query(lc[o], l, mid, k);
else return sumv[lc[o]] + query(rc[o], mid + 1, r, k - siz[lc[o]]);
}
LL Query(int p, int k) {
if(k > p) return ool;
return query(rt[p], 1, n, k) + Info[p].x;
}
void process(int l, int r, int ql, int qr, LL *ans) {
int mid = ql + qr >> 1;
LL res = ool, opt;
rep(i, l, r) {
LL tmp = Query(i, mid);
if(res > tmp) res = tmp, opt = i;
}
ans[mid] = res;
if(ql == qr) return ;
process(l, opt, ql, mid, ans);
process(opt, r, mid + 1, qr, ans);
return ;
}
void solve(LL *ans, int N) {
ToT = 0; memset(lc, 0, sizeof(lc)); memset(rc, 0, sizeof(rc));
rep(i, 1, N) update(rt[i], rt[i-1], 1, n, Info[i].y);
process(1, N, 1, N, ans);
return ;
}
LL ans1[maxn], ans2[maxn];
int main() {
n = read(); lim = read();
rep(i, 1, n) dis[i] = read(), num[i] = Time[i] = read();
sort(num + 1, num + n + 1);
rep(i, 1, n) Time[i] = lower_bound(num + 1, num + n + 1, Time[i]) - num;
int ans = 0;
Info[1] = mp(0, Time[1]);
rep(i, 2, n) Info[i] = mp(Info[i-1].x + (dis[i-1] << 1), Time[i]);
solve(ans1, n);
Info[1] = mp(dis[n], Time[n]);
rep(i, 2, n - 1) Info[i] = mp(Info[i-1].x + dis[n-i+1], Time[n-i+1]);
solve(ans2, n - 1);
rep(i, 1, n) if(ans1[i] <= lim) ans = max(ans, (int)(i + upper_bound(ans2 + 1, ans2 + n, lim - ans1[i]) - ans2 - 1));
rep(i, 1, n - 1) if(ans2[i] <= lim) ans = max(ans, i);
Info[1] = mp(0, Time[1]);
rep(i, 2, n) Info[i] = mp(Info[i-1].x + dis[i-1], Time[i]);
solve(ans1, n);
Info[1] = mp(dis[n] << 1, Time[n]);
rep(i, 2, n - 1) Info[i] = mp(Info[i-1].x + (dis[n-i+1] << 1), Time[n-i+1]);
solve(ans2, n - 1);
rep(i, 1, n) if(ans1[i] <= lim) ans = max(ans, (int)(i + upper_bound(ans2 + 1, ans2 + n, lim - ans1[i]) - ans2 - 1));
rep(i, 1, n - 1) if(ans2[i] <= lim) ans = max(ans, i);
printf("%d\n", ans);
return 0;
}
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania的更多相关文章
- 清北学堂2017NOIP冬令营入学测试P4745 B’s problem(b)
清北学堂2017NOIP冬令营入学测试 P4745 B's problem(b) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描 ...
- 清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)
清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算 ...
- noi2019模拟测试赛(四十七)
noi2019模拟测试赛(四十七) T1与运算(and) 题意: 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...
- 清北学堂2017NOIP冬令营入学测试P4749 C’s problem(c)
P4746 C's problem(c) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描述 小C是一名数学家,由于它自制力比较差 ...
- 清北学堂2017NOIP冬令营入学测试P4749 F’s problem(f)
时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 这个故事是关于小F的,它有一个怎么样的故事呢. 小F是一个田径爱好者,这天它们城市里正在 ...
- 2018.8.8 Noip2018模拟测试赛(二十一)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 112分(OvO) 题目目录: T1:幸福的道路 T2:Solitaire T3:Flags 赛后心得: 第一题裸树d啊! ...
- 2018.8.7 Noip2018模拟测试赛(二十)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 100分(呵呵一笑) 题目列表: T1:SS T2:Tree Game T3:二元运算 赛后反思: Emmmmmm…… 开 ...
- 2018.7.31 Noip2018模拟测试赛(十六)
日期: 七月最后一天 总分: 300分 难度: 提高 ~ 省选 得分: 30分(少的可怜) 我太弱了:(题目目录) T1:Mushroom追妹纸 T2:抵制克苏恩 T3:美味 失分分析:(QA ...
- noip2017集训测试赛(十一)Problem C: 循环移位
题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 ...
随机推荐
- web开发学习路线
第一阶段: HTML+CSS: HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础: Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMA ...
- weui-switch开关控件,表单提交后如何取值
最近在学习weui这个框架,做了一些小的试验,发现weui-switch控件直接提交不能获取到表单信息,在segmentfault上发现也有人提了这个问题,有人说可以设置一个隐含标签来捕获开关的状态, ...
- Python学习手册之函数和模块
在上一篇文章中,我们介绍了 Python 的控制结构,现在我们介绍 Python 函数和模块. 查看上一篇文章请点击:https://www.cnblogs.com/dustman/p/9976234 ...
- Java8新特性(一)——Lambda表达式与函数式接口
一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...
- windows系统下npm升级的正确姿势以及原理
本文来自网易云社区 作者:陈观喜 网上关于npm升级很多方法多种多样,但是在windows系统下不是每种方法都会正确升级.其中在windows系统下主要的升级方法有以下三种: 首先最暴力的方法删掉no ...
- NoSQL简单学习(一)
只是简单的知道有这个东西,却从来没有去接触,今天看了几篇文章,记录一下,开始慢慢接触这一领域 简介: 8种Nosql数据库系统对比 http://blog.jobbole.com/1344/ 一网打尽 ...
- mcrouter facebook 开源的企业级memcached代理
原文地址:https://code.facebook.com/posts/296442737213493/introducing-mcrouter-a-memcached-protocol-route ...
- 微信营销 推广 会议签到 活动签到 复用微信3D动画签到系统
适用场合 本软件适合各行各业,尤其世界500强上市公司,推广产品,聚集微信粉丝和人气.如大型展销会,新产品发布,主题活动推广,年会晚会等.各种商业和演出场合. 软件有试用版可供下载试用. 特色功能 顾 ...
- Java Set集合(HashSet、TreeSet)
什么是HashSet?操作过程是怎么样的? 1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构 2.哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素 ...
- 虚拟现实-VR-UE4-创建C++版工程
首先,创建C++版本的UE4 项目工程,我使用的是4.12.3版本,据了解,新版本后面的编译都是vs2015 所以,想要创建C++版本的工程,就需要安装vs2015 至于vs2015的安装,自己百度吧 ...