BZOJ1367 [Baltic2004]sequence 堆 左偏树
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1367
题意概括
Description
Input
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; }