【UOJ #29】【IOI 2014】holiday
http://uoj.ac/problem/29
cdq四次处理出一直向左, 一直向右, 向左后回到起点, 向右后回到起点的dp数组,最后统计答案。
举例:\(fi\)表示一直向右走i天能参观的最多景点数。
其中有一个很重要的条件\(fi≤fi+1fi≤fi+1\),这个条件是分治的前提。
关于这个条件的证明,我想了好久才想出来,用反证法证明一下就行。
分治时需要用主席树维护路径上的前k大和。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include"holiday.h"
using namespace std;
typedef long long ll;
const int N = 100003;
const int M = 250003;
struct node {
int l, r, s;
ll sum;
node() {l = r = s = sum = 0;}
} T[N * 20];
int a[N], H[N], cnt = 0, root[N], top, st;
ll f[M], g[M], f1[M], g1[M];
void update(int &pos, int l, int r, int key) {
T[++cnt] = T[pos]; pos = cnt;
++T[pos].s; T[pos].sum += H[key];
if (l == r) return;
int mid = (l + r) >> 1;
if (key <= mid) update(T[pos].l, l, mid, key);
else update(T[pos].r, mid + 1, r, key);
}
ll query(int tl, int tr, int l, int r, int num) {
if (l == r) {return min(T[tr].sum - T[tl].sum, 1ll * H[l] * num);}
int mid = (l + r) >> 1, s = T[T[tr].r].s - T[T[tl].r].s;
if (s >= num)
return query(T[tl].r, T[tr].r, mid + 1, r, num);
else
return T[T[tr].r].sum - T[T[tl].r].sum + query(T[tl].l, T[tr].l, l, mid, num - s);
}
void cdq_f(int l, int r, int tmp_l, int tmp_r) {
if (l > r) return;
int mid = (l + r) >> 1, pos = tmp_l;
ll t;
for(int i = tmp_l; i - st <= mid && i <= tmp_r; ++i)
if ((t = query(root[st - 1], root[i], 1, top, mid - i + st)) > f[mid])
f[mid] = t, pos = i;
cdq_f(l, mid - 1, tmp_l, pos);
cdq_f(mid + 1, r, pos, tmp_r);
}
void cdq_f1(int l, int r, int tmp_l, int tmp_r) {
if (l > r || tmp_l > tmp_r) return;
int mid = (l + r) >> 1, pos = tmp_l;
ll t;
for(int i = tmp_l; ((i - st) << 1) <= mid && i <= tmp_r; ++i)
if ((t = query(root[st], root[i], 1, top, mid - ((i - st) << 1))) > f1[mid])
f1[mid] = t, pos = i;
cdq_f1(l, mid - 1, tmp_l, pos);
cdq_f1(mid + 1, r, pos, tmp_r);
}
void cdq_g(int l, int r, int tmp_l, int tmp_r) {
if (l > r) return;
int mid = (l + r) >> 1, pos = tmp_r;
ll t;
for(int i = tmp_r; st - i <= mid && i >= tmp_l; --i) {
if ((t = query(root[i - 1], root[st], 1, top, mid - st + i)) > g[mid])
g[mid] = t, pos = i;
}
cdq_g(l, mid - 1, pos, tmp_r);
cdq_g(mid + 1, r, tmp_l, pos);
}
void cdq_g1(int l, int r, int tmp_l, int tmp_r) {
if (l > r || tmp_l > tmp_r) return;
int mid = (l + r) >> 1, pos = tmp_r;
ll t;
for(int i = tmp_r; ((st - i) << 1) <= mid && i >= tmp_l; --i) {
if ((t = query(root[i - 1], root[st - 1], 1, top, mid - ((st - i) << 1))) > g1[mid])
g1[mid] = t, pos = i;
}
cdq_g1(l, mid - 1, pos, tmp_r);
cdq_g1(mid + 1, r, tmp_l, pos);
}
ll findMaxAttraction(int n, int start, int d, int attraction[]) {
for(int i = 0; i < n; ++i) H[++cnt] = attraction[i];
sort(H + 1, H + cnt + 1);
cnt = unique(H + 1, H + cnt + 1) - H;
for(int i = 1; i <= n; ++i) a[i] = lower_bound(H + 1, H + cnt, attraction[i - 1]) - H;
top = cnt - 1; cnt = 0;
for(int i = 1; i <= n; ++i) {
root[i] = root[i - 1];
update(root[i], 1, top, a[i]);
}
st = start + 1;
cdq_f(0, d, st, n);
cdq_f1(0, d, st + 1, n);
cdq_g(0, d, 1, st);
cdq_g1(0, d, 1, st - 1);
ll ans = max(f[d], g[d]);
for(int i = 1; i <= d; ++i)
ans = max(ans, max(f[i] + g1[d - i], g[i] + f1[d - i]));
return ans;
}
UOJ上是交互题的形式
【UOJ #29】【IOI 2014】holiday的更多相关文章
- JAVA 基础编程练习题29 【程序 29 求矩阵对角线之和】
29 [程序 29 求矩阵对角线之和] 题目:求一个 3*3 矩阵对角线元素之和 程序分析:利用双重 for 循环控制输入二维数组,再将 a[i][i]累加后输出. package cskaoyan; ...
- uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题
[清华集训2014]矩阵变换 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...
- AC日记——【清华集训2014】奇数国 uoj 38
#38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...
- [官方软件] Easy Sysprep v4.3.29.602 【系统封装部署利器】(2016.01.22)--skyfree大神
[官方软件] Easy Sysprep v4.3.29.602 [系统封装部署利器](2016.01.22) Skyfree 发表于 2016-1-22 13:55:55 https://www.it ...
- 【UOJ】67 新年的毒瘤 &【BZOJ】1123 BLO
[UOJ 67] 题目链接: 传送门 题解: 第一眼很懵逼……这什么鬼. 思考什么点复合条件……(o(>﹏<)o 1.树,也就是说还剩n-2条边,等价于要删去一个度数为m-n+2的点. 2 ...
- 【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)
[UOJ#236][IOI2016]railroad(欧拉回路,最小生成树) 题面 UOJ 题解 把速度看成点,给定的路段看成边,那么现在就有了若干边,然后现在要补上若干边,以及一条\([inf,\) ...
- 【UOJ#177】欧拉回路
[UOJ#177]欧拉回路 题面 UOJ 题解 首先图不连通就没啥好搞的了. 对于无向图而言,每个点度数为偶数. 对于有向图而言,每个点入度等于出度. 然后就是一本通上有的做法,直接\(dfs\)一遍 ...
- 【UOJ#311】【UNR #2】积劳成疾(动态规划)
[UOJ#311][UNR #2]积劳成疾(动态规划) UOJ Solution 考虑最大值分治解决问题.每次枚举最大值所在的位置,强制不能跨过最大值,左右此时不会影响,可以分开考虑. 那么设\(f[ ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
随机推荐
- NOIP2015子串[序列DP]
题目背景 无 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重 叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个 ...
- Integer & int & == & equals
int 是基本类型,直接存数值,integer是对象,用一个引用指向这个对象 int 是基本数据类型,Integer是类 int类的变量初始为0,Integer的变量则初始化为null. 如果只是用来 ...
- AC日记——石头剪刀布 openjudge 1.6 08
08:石头剪刀布 总时间限制: 1000ms 内存限制: 65536kB 描述 石头剪刀布是常见的猜拳游戏.石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负. 一天,小A和小B正好在 ...
- pitch yaw roll 的区别
http://blog.163.com/vipwdp@126/blog/static/150224366201281935518196/
- crontab日常使用梳理
在日常的运维工作中,对crontab定时任务的制定是再寻常不过的了.根据以往的使用经验梳理如下: 基本格式 :* * * * * command分 时 日 月 周 命令解释:第1列表示分钟1-59 每 ...
- DEDECMS之一 安装配置
一.织梦安装 1.建好数据库.数据库用户名密码以及权限 2.上传代码到服务器,根目录赋予所有权限 3.打开网址,一步步安装即可 二.配置 1.删除安装目录下的所有文件 2.系统 系统设置:配置网站基本 ...
- ASP.NET整理:Cookie,Application,Session,页面生命周期
一.设置Cookie的2种方式 1. Repsonse.Cookie[“名”] = 值; 2. HttpCookie hcCookie = new HttpCookie(“名”,值); h ...
- junit
junit测试代码也视为开发内容的一部分,强烈建议在开发过程中编写junit代码作为开发调试工具,用junit调试代码不需要启动应用服务器,实际上会加快开发速度.
- 拥抱HTML5 — Page Visibility(页面可见性) API介绍
H5 提供了很多简单实用的 API,Page Visibility API 就是其中之一. 不知道用户是不是在与页面交互,这是困扰广大 Web 开发人员的一个主要问题.如果 页面最小化了 或者 隐藏在 ...
- C语言strcat()函数:连接字符串
头文件:#include <string.h> strcat() 函数用来连接字符串,其原型为: char *strcat(char *dest, const char *src); ...