码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ 1367】 [Baltic2004]sequence

时间:2015-02-27 10:12:17      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:bzoj   oi   可合并堆   

1367: [Baltic2004]sequence

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 631  Solved: 215
[Submit][Status]

Description

技术分享

Input

技术分享

Output

一个整数R

Sample Input

7
9
4
8
20
14
15
18

Sample Output

13

HINT

所求的Z序列为6,7,8,13,14,15,18.
R=13



左偏树。


详细题解(在P13)。


这个题解求的z是不减的,要求单增的话只要把a[i]减i再算即可。


很巧妙的是用左偏树来合并两个区间的中位数。


根据题解,前一个区间的中位数大于后一个区间的中位数,合并之后中位数只会变小,因此先把两个对合并(大根堆),然后把最大的一个个除去,最后剩下一半即可,最大的那个就是中位数。


一定要注意,这里的“一半”一定要向上取整!!因为如果两个区间原本都是3个,向下取整都变成1个,合并之后6个只剩下2个了。。


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define M 1050000
using namespace std;
int n,a[M],root[M],l[M],r[M],w[M],tot=0,cnt=0;
struct Ltree
{
	int size,l,r,dis,v;
}t[M];
void read(int &tmp)
{
	tmp=0;
	char ch=getchar();
	int fu=1;
	for (;ch<'0'||ch>'9';ch=getchar())
		if (ch=='-') fu=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())
		tmp=tmp*10+ch-'0';
	tmp*=fu;
}
int New_heap(int x)
{
	t[x].v=a[x];
	t[x].l=t[x].r=t[x].dis=0;
	t[x].size=1;
	return x;
}
int Merge(int x,int y)
{
	if ((!x)||(!y)) return x+y;
	if (t[x].v<t[y].v)
		swap(x,y);
	t[x].size+=t[y].size;
	t[x].r=Merge(t[x].r,y);
	if (t[t[x].l].dis<t[t[x].r].dis)
		swap(t[x].l,t[x].r);
	t[x].dis=t[t[x].r].dis+1;
	return x;
}
int Del(int x)
{
	return Merge(t[x].l,t[x].r);
}
int main()
{
	read(n);
	for (int i=1;i<=n;i++)
		read(a[i]),a[i]-=i;
	tot=0;
	t[0].dis=-1;
	for (int i=1;i<=n;i++)
	{
		root[++tot]=New_heap(i);
		w[tot]=a[i];
		l[tot]=r[tot]=i;
		while (tot>1&&w[tot-1]>w[tot])
		{
			tot--;
			r[tot]=r[tot+1];
			root[tot]=Merge(root[tot],root[tot+1]);
			int x=(r[tot]-l[tot]+2)/2;
			while (t[root[tot]].size>x)
				root[tot]=Del(root[tot]);
			w[tot]=t[root[tot]].v;
		}
	}
	long long ans=0LL;
	for (int i=1;i<=tot;i++)
		for (int j=l[i];j<=r[i];j++)
			ans+=abs(a[j]-w[i]);
	printf("%lld\n",ans);
	return 0;
}


技术分享

【BZOJ 1367】 [Baltic2004]sequence

标签:bzoj   oi   可合并堆   

原文地址:http://blog.csdn.net/regina8023/article/details/43958073

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!