bzoj 1367: [Baltic2004]sequence(中位数+可并堆)
2016-05-08 17:16
661 查看
1367: [Baltic2004]sequence
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 935 Solved: 351
[Submit][Status][Discuss]
Description
![](http://www.lydsy.com/JudgeOnline/images/1367_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1367_2.jpg)
Output
一个整数RSample Input
79
4
8
20
14
15
18
Sample Output
13HINT
所求的Z序列为6,7,8,13,14,15,18.R=13
Source
[Submit][Status][Discuss]
题解:中位数+可并堆
分情况讨论一下:
一个区间[l, r],递增的,则对于此区间最优解为z[i] = t[i];
一个区间[l,r] ,递减的,则z[l] = z[l + 1] = ... = z[r] = 这段数的中位数,不妨叫做w。(中位数为第(r - l + 1) / 2大的数),为什么是中位数呢,因为区间是递减的,我们要把他变成不下降的,最小的改动情况就是把他改成一个每个数都相同的序列,那么这就转化成了中位数问题,因为所有点到中位数的距离是最小的。但是我们要求的是上升序列而不是不下降序列,所以需要将将v[i]处理成v[i]-i。
那么这样就可以做了,对于递增的区间,我们可以把区间中的每一个数看成一个单独的堆,那么这个堆维护的中位数就是他本身。如果要加入一个数,我们可以把这个点先看成一个单独的堆,如果v[root[now]]<v[root[now]]也就是当前这个点,比他的前一个区间的中位数要小,但是我们要求他递增,那么这个问题又转换成了“一个区间[l,r]
,递减的,则z[l] = z[l + 1] = ... = z[r] = 这段数的中位数”这个问题,我们可以用可并堆来将两个合并到一起。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 1000003 using namespace std; int n,m; int v ,l ,r ,R ,L ,size ,tot ,root ,d ; int merge(int x,int y) { if (!x) return y; if (!y) return x; if (v[x]<v[y]) swap(x,y); R[x]=merge(R[x],y); size[x]=size[L[x]]+size[R[x]]+1; if (d[L[x]]<=d[R[x]]) swap(L[x],R[x]); d[x]=d[R[x]]+1; return x; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&v[i]),v[i]=v[i]-i; int now=0; for (int i=1;i<=n;i++) { now++; root[now]=i; l[now]=r[now]=i; //所控制区间的左右端点 tot[now]=1;//当前堆维护的中位数控制的数的个数 size[root[now]]=1;//堆中元素的个数 while (now>1&&v[root[now-1]]>v[root[now]]) { now--; r[now]=r[now+1]; tot[now]+=tot[now+1]; root[now]=merge(root[now],root[now+1]); while (size[root[now]]*2>tot[now]+1)//保证堆顶元素是当前区间的中位数 root[now]=merge(L[root[now]],R[root[now]]); } } long long ans=0; for (int i=1;i<=now;i++) for (int j=l[i];j<=r[i];j++) ans+=(long long)abs(v[j]-v[root[i]]); printf("%I64d\n",ans); }
相关文章推荐
- Error getting nested result map values for 'user_inf'. Cause: java.sql.SQLException: Cannot convert
- 百度编辑器ueditor的简单使用
- paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之output encoded style with registered outputs(Good style)
- UE4:关闭自动曝光
- mapreduece和Hadoop啥关系
- UI进阶 数据库 SQLite
- 300. Longest Increasing Subsequence 最长子序列
- BSCMAKE: error BK1513 : nonincremental update requires all .SBR files
- UESTC--1041--Hug the princess(位运算)
- 阿里巴巴Druid连接池配置
- 语法篇5之关键词void、break、continue、new
- easyUi 修改页面
- easyUi 新增页面
- easyUI 增删改
- subarray、subsequence的区别
- Base64图片与UIImage的相互转化
- Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor (括号匹配和删除,输出最后的括号序列)
- 【LeetCode】Implement Queue using Stacks 解题报告
- GUI--统计按钮单击次数
- IOS控件学习:UILabel常用属性与用法