【bzoj1367】左偏树
2015-05-30 09:09
225 查看
1367: [Baltic2004]sequence
Description
![](http://www.lydsy.com/JudgeOnline/images/1367_1.jpg)
这道题的结论证明参见 论文
对于求不下降序列 最后的做法就是:维护几段连续的序列,使它们的中位数不下降
然而转化到递增序列,我们只需要将每个数读进来的之后减去它的下标就可以了
所以我们对于每一段已求好的序列,既要维护它的中位数,又要支持合并
因为我们合并的前提是:中位数(i)>中位数(i+1),那么对于合并后的i而言,中位数肯定是不升的
根据这个性质我们又可以用可并堆了,堆顶元素表示该序列中的中位数
当堆的元素个数*2>序列长度+1的时候就可以弹出堆顶
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <string> #define Rep(i, x, y) for (int i = x; i <= y; i ++) #define RepE(i, x) for (int i = pos[x]; i; i = g[i].nex) #define Dwn(i, x, y) for (int i = x; i >= y; i --) #define u t[x] #define v t[y] #define Lc t[ u.lc ] #define Rc t[ u.rc ] using namespace std; typedef long long LL; const int N = 1000005; struct arr { int lc, rc, vl, d; } t ; int n, ro , l , s , a , m, l1 , r1 ; LL ans; int Merge(int x, int y) { if (!x || !y) return x + y; if (u.vl < v.vl) swap(x, y); u.rc = Merge(u.rc, y); if (Rc.d > Lc.d) swap(u.rc, u.lc); u.d = Rc.d + 1; return x; } int Del(int x) { return Merge(u.lc, u.rc); } int main() { scanf ("%d", &n); Rep(i, 1, n) { scanf ("%d", &a[i]), a[i] -= i; } Rep(i, 1, n) { t[ro[++ m] = i].vl = a[i], l[m] = s[m] = 1, l1[m] = r1[m] = i; while (m > 1 && t[ ro[m-1] ].vl > t[ ro[m] ].vl) { l[m-1] = l[m] + l[m-1], s[m-1] += s[m]; ro[m - 1] = Merge(ro[m], ro[m-1]); m --, r1[m] = i; while (l[m] > (s[m] + 1) / 2) ro[m] = Del(ro[m]), l[m] --; } } Rep(i, 1, m) { int k = t[ ro[i] ].vl; Rep(j, l1[i], r1[i]) { ans += abs(a[j] - k); } } printf("%lld\n", ans); return 0; }
相关文章推荐
- Eclipse和MyEclipse 手动设置 Java代码 注释模板
- Mongodb配置
- nginx+mongodb-gridfs+squid
- microsoft office 2016 preview 下载试用
- double类型保留两位小数
- 基于MongoDB GridFS的图片存储
- 学会爱
- wpbakery Visual Composer - web网页可视化 编辑器 介紹
- Oracle学习(六)之增加日志组成员
- rabbitmq-server 安装方法
- Java IO流:
- ScrollView中嵌套ListView
- jsp+servlet更改模板
- Linux Mint (应用软件— 文件阅读器:Evince)
- JavaScript获取事件对象和目标对象
- 为ListView每个Item上面的按钮添加事件
- eclipse 添加tomcat插件
- 设计模式之抽象工厂模式
- `cocos2dx非完整` 日志模块 增量更新
- Vuforia SDK---- AR开发vuforia 问题总结