现学的左偏树。。。这可是道可并堆的好题目。

首先我们考虑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的更多相关文章

  1. BZOJ1367 [Baltic2004]sequence 堆 左偏树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...

  2. BZOJ1367 [Baltic2004]sequence 【左偏树】

    题目链接 BZOJ1367 题解 又是一道神题,, 我们考虑一些简单的情况: 我们先假设\(b_i\)单调不降,而不是递增 对于递增序列\(\{a_i\}\),显然答案\(\{b_i\}\)满足\(b ...

  3. BZOJ1367——[Baltic2004]sequence

    1.题目大意:给一个序列t,然后求一个序列z,使得$|z1-t1|+|z2-t2|+...+|zn-tn|$的值最小,我们只需要求出这个值就可以了,并且z序列是递增的 2.分析:这道题z序列是递增的, ...

  4. 可并堆试水--BZOJ1367: [Baltic2004]sequence

    n<=1e6个数,把他们修改成递增序列需把每个数增加或减少的总量最小是多少? 方法一:可以证明最后修改的每个数一定是原序列中的数!于是$n^2$DP(逃) 方法二:把$A_i$改成$A_i-i$ ...

  5. BZOJ1367: [Baltic2004]sequence(左偏树)

    Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...

  6. bzoj1367 [Baltic2004]sequence 左偏树+贪心

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1367 题解 先考虑条件为要求不下降序列(不是递增)的情况. 那么考虑一段数值相同的子段,这一段 ...

  7. 【BZOJ1367】[Baltic2004]sequence 左偏树

    [BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...

  8. 【bzoj1367】[Baltic2004]sequence

    2016-05-31 17:31:26 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1367 题解:http://www.cnblogs.co ...

  9. 【BZOJ-1367】sequence 可并堆+中位数

    1367: [Baltic2004]sequence Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 932  Solved: 348[Submit][S ...

随机推荐

  1. DOS命令符基本操作

    怎么改变DOS默认路径 开始->所有程序->附件->命令提示符,在“命令提示符”上右键,选择“属性”,(或者在快捷方式上点击属性)会弹出一个“命令提示符 属性”对话框,可以通过修改该 ...

  2. python 列表转为字典的两个小方法

    1.现在有两个列表,list1 = ['key1','key2','key3']和list2 = ['1','2','3'],把他们转为这样的字典:{'key1':'1','key2':'2','ke ...

  3. [转]C程序内存区域分配(5个段作用)

    [转]C程序内存区域分配(5个段作用) 2012-08-10 14:45:32|  分类: C++基础|字号 订阅     参考:http://www.360doc.com/content/11/03 ...

  4. 【回溯】图的m着色问题

    问题 C: [回溯]图的m着色问题 时间限制: 1 Sec  内存限制: 128 MB提交: 1  解决: 1[提交][状态][讨论版] 题目描述 给定无向连通图G=(V, E)和m种不同的颜色,用这 ...

  5. UVALive 7040 Color (容斥原理+逆元+组合数+费马小定理+快速幂)

    题目:传送门. 题意:t组数据,每组给定n,m,k.有n个格子,m种颜色,要求把每个格子涂上颜色且正好适用k种颜色且相邻的格子颜色不同,求一共有多少种方案,结果对1e9+7取余. 题解: 首先可以将m ...

  6. Eclipse中android工程C++文件中出现的莫名其妙的错误

    大多数是std库相关的问题,例如 vector<int> v; v.push_back(23);//这句语法是没有错误的,但是每次执行Run As的时候就会报错 尝试1:在工程名右键-Cl ...

  7. [Android Pro] 监听Blutooth打开广播

    <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission a ...

  8. Java查询网址

    Java在线帮助文档: http://docs.oracle.com/javase/8/docs/technotes/guides/desc_jdk_structure.html Java小知识讲解: ...

  9. Linux防火墙规则的查看、添加、删除和修改

    这里只列出比较常用的参数,详细的请查看man iptables 1.查看 iptables -nvL –line-number -L查看当前表的所有规则,默认查看的是filter表,如果要查看NAT表 ...

  10. Java Hour 16 来个CURD吧!

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 突然想到我最近一直在追的小说,作者每天都会更新两章,而且质量挺高.所以从这篇开 ...