BZOJ1367 [Baltic2004]sequence
现学的左偏树。。。这可是道可并堆的好题目。
首先我们考虑z不减的情况:
我们发现对于一个区间[l, r],里面是递增的,则对于此区间最优解为z[i] = t[i];
如果里面是递减的,z[l] = z[l + 1] = ... = z[r] = 这段数的中位数,不妨叫做w。(此处我们定义中位数为第(r - l + 1) / 2大的数,因为这并不影响结果)
而其实递增可以转化为每一段只有一个点,就等价于递减了。
那么我们把原数列分段,每段都是递减的,而每一段的z都是那段的中位数w。这样就找到了最优解。(证略)
这样就有了解法:
(1)新加入一个数至数列末端,先把它当成单独一段
(2)每次看最后一段的w[tot]和前一段的w[tot - 1],若w[tot] < w[tot - 1],则说明合并可以更优,合并这两段。
(3)最后计算ans
这之中还有一个问题:z[i]不是不减而是递增。有个巧妙地办法:让z[i](新) = z[i](老) - i即可,这样就保证了z的递增性质。
/**************************************************************
Problem: 1367
User: rausen
Language: C++
Result: Accepted
Time:5284 ms
Memory:59400 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int N = ; struct heap{
int v, l, r, dep;
}h[N];
int l[N], r[N], cnt[N], num[N], root[N];
int z[N];
int n, tot, Cnt; inline int read(){
int x = , sgn = ;
char ch = getchar();
while (ch < '' || ch > ''){
if (ch == '-') sgn = -;
ch = getchar();
}
while (ch >= '' && ch <= ''){
x = x * + ch - '';
ch = getchar();
}
return sgn * x;
} int new_heap(int x){
h[++Cnt].v = x;
h[Cnt].l = h[Cnt].r = h[Cnt].dep = ;
return Cnt;
} int Merge(int x, int y){
if (!x || !y) return x + y;
if (h[x].v < h[y].v)
swap(x, y);
h[x].r = Merge(h[x].r, y);
if (h[h[x].l].dep < h[h[x].r].dep)
swap(h[x].l, h[x].r);
h[x].dep = h[h[x].r].dep + ;
return x;
} int Top(int x){
return h[x].v;
} int Pop(int x){
return Merge(h[x].l, h[x].r);
} int main(){
n = read();
for (int i = ; i <= n; ++i)
z[i] = read() - i; for (int i = ; i <= n; ++i){
++tot;
root[tot] = new_heap(z[i]);
cnt[tot] = , num[tot] = ;
l[tot] = i, r[tot] = i; while (tot > && Top(root[tot]) < Top(root[tot - ])){
--tot;
root[tot] = Merge(root[tot], root[tot + ]);
num[tot] += num[tot + ], cnt[tot] += cnt[tot + ], r[tot] = r[tot + ];
for(; cnt[tot] * > num[tot] + ; --cnt[tot])
root[tot] = Pop(root[tot]);
}
} long long ans = ;
for (int i = ; i <= tot; ++i)
for (int j = l[i], w = Top(root[i]); j <= r[i]; ++j)
ans += abs(z[j] - w);
printf("%lld\n", ans);
return ;
}
(p.s. 真是写的矬死了。。。越优化又慢,都醉了)
BZOJ1367 [Baltic2004]sequence的更多相关文章
- BZOJ1367 [Baltic2004]sequence 堆 左偏树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...
- BZOJ1367 [Baltic2004]sequence 【左偏树】
题目链接 BZOJ1367 题解 又是一道神题,, 我们考虑一些简单的情况: 我们先假设\(b_i\)单调不降,而不是递增 对于递增序列\(\{a_i\}\),显然答案\(\{b_i\}\)满足\(b ...
- BZOJ1367——[Baltic2004]sequence
1.题目大意:给一个序列t,然后求一个序列z,使得$|z1-t1|+|z2-t2|+...+|zn-tn|$的值最小,我们只需要求出这个值就可以了,并且z序列是递增的 2.分析:这道题z序列是递增的, ...
- 可并堆试水--BZOJ1367: [Baltic2004]sequence
n<=1e6个数,把他们修改成递增序列需把每个数增加或减少的总量最小是多少? 方法一:可以证明最后修改的每个数一定是原序列中的数!于是$n^2$DP(逃) 方法二:把$A_i$改成$A_i-i$ ...
- BZOJ1367: [Baltic2004]sequence(左偏树)
Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...
- bzoj1367 [Baltic2004]sequence 左偏树+贪心
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1367 题解 先考虑条件为要求不下降序列(不是递增)的情况. 那么考虑一段数值相同的子段,这一段 ...
- 【BZOJ1367】[Baltic2004]sequence 左偏树
[BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...
- 【bzoj1367】[Baltic2004]sequence
2016-05-31 17:31:26 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1367 题解:http://www.cnblogs.co ...
- 【BZOJ-1367】sequence 可并堆+中位数
1367: [Baltic2004]sequence Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 932 Solved: 348[Submit][S ...
随机推荐
- webservice远程调试开启
在.NET 中已经默认将WEBSERVICE的远程调试功能关闭,有的时候我们需要远程调试程序的时候,就需要打开此功能我们只需在WEBSERVICE的项目的中添web.config的<system ...
- 【云计算】ubuntu下docker安装配置指南
Docker Engine安装配置 以下描述仅Docker在Ubuntu Precise 12.04 (LTS).Ubuntu Trusty 14.04 (LTS).Ubuntu Wily 15.10 ...
- jQuery 效果函数
jQuery 效果函数 方法 描述 animate() 对被选元素应用“自定义”的动画 clearQueue() 对被选元素移除所有排队的函数(仍未运行的) delay() 对被选元素的所有排队函数( ...
- Android简易数据存储之SharedPreferences
Andorid提供了多种数据存储的方式,例如前面说到的“Android数据存储之SQLite的操作”是用于较复杂的数据存储.然而,如果有些简单的数据存储如果采用SQLite的方式的话会显得比较笨重.例 ...
- Android studio 程序升级和sdk manager 升级方法
在中国使用android有点郁闷,经常被屏蔽.常遇到2个升级问题,现在总结如下: 1.android studio升级时提示 Connection failed. Please check your ...
- 到天宫做客-最后一分钟AC!!!
问题 C: 到天宫做客 时间限制: 1 Sec 内存限制: 128 MB提交: 100 解决: 26[提交][状态][讨论版] 题目描述 有一天,我做了个梦,梦见我很荣幸的接到了猪八戒的邀请,到天 ...
- jquery给height拼接动态变量
var sizeLength = "${list.size()}"; if(sizeLength==''){ sizeLength=0; } sizeLength=400*size ...
- 【数据结构】Huffman树
参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小 ...
- 开源混淆工具ProGuard配置详解及配置实例
ProGuard的作用: 1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用. 2.创建的程序和程序库很难使用反向工程. 3.所以它能删除来自源文件中的没有调用的代码 4.充分利 ...
- windows设置java环境变量
JAVA_HOME C:\Program Files\java\jdk1.6.0_38 path %JAVA_HOME%\bin; CLASSPATH .;%JAVA_HOME%\lib\dt.jar ...