去博客园看该题解


题目传送门 - BZOJ1367


题意概括

Description

BZOJ1367 [Baltic2004]sequence 堆 左偏树

Input

BZOJ1367 [Baltic2004]sequence 堆 左偏树

Output

一个整数R

题解

我被自己坑死了。
左偏树合并:
	if (a==0||b==0)
		return a+b;

这样是对的。

然而:

	if (a*b==0)
		return a+b;

这样是错的。

原因是:a*b会爆int……


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1000005;
int n,v[N],root[N],L[N],R[N],top;
int ls[N],rs[N],npl[N],size[N],val[N];
void make_heap(int x,int v){
	ls[x]=rs[x]=npl[x]=0,val[x]=v,size[x]=1;
}
int merge(int a,int b){
	if (1LL*a*b==0)
		return a+b;
	if (val[a]<val[b])
		swap(a,b);
	rs[a]=merge(rs[a],b);
	if (npl[rs[a]]>npl[ls[a]])
		swap(rs[a],ls[a]);
	npl[a]=npl[rs[a]]+1;
	size[a]=size[ls[a]]+size[rs[a]]+1;
	return a;
}
void pop(int &x){
	x=merge(ls[x],rs[x]);
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&v[i]),v[i]-=i;
	top=0;
	for (int i=1;i<=n;i++){
		make_heap(root[++top]=i,v[i]);
		L[top]=R[top]=i;
		while (top>1&&val[root[top-1]]>val[root[top]]){
			top--;
			root[top]=merge(root[top],root[top+1]);
			R[top]=R[top+1];
			while (size[root[top]]*2>R[top]-L[top]+2)
				pop(root[top]);
		}
	}
	LL ans=0;
	for (int i=1;i<=top;i++)
		for (int j=L[i];j<=R[i];j++)
			ans+=abs(val[root[i]]-v[j]);
	printf("%lld",ans);
	return 0;
} 

  

相关文章:

  • 2021-06-08
  • 2021-09-03
  • 2022-12-23
  • 2022-02-16
  • 2021-05-18
  • 2021-12-31
  • 2021-10-23
  • 2022-01-14
猜你喜欢
  • 2021-10-21
  • 2021-10-16
  • 2021-08-29
  • 2022-02-23
  • 2021-08-17
  • 2021-12-14
相关资源
相似解决方案