[可并堆] Bzoj P1367 sequence

Posted comfortable

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[可并堆] Bzoj P1367 sequence相关的知识,希望对你有一定的参考价值。

Description

技术图片

 

题解

 

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #define N 1000010
 5 using namespace std;
 6 struct ltree
 7 
 8     int cnt,l[N],r[N],v[N],sz[N],d[N];
 9     int merge(int x,int y)
10     
11         if (x==0||y==0) return x+y;
12         if (v[x]<v[y]) swap(x,y);
13         r[x]=merge(r[x],y),sz[x]=sz[l[x]]+sz[r[x]]+1;
14         if (d[r[x]]>d[l[x]]) swap(l[x],r[x]);
15         d[x]=d[r[x]]+1;
16         return x;
17     
18     int top(int x)  return v[x]; 
19     int size(int x)  return sz[x]; 
20     void pop(int &x)  x=merge(l[x],r[x]); 
21     int new_heap(int x)  v[++cnt]=x,sz[cnt]=1,l[cnt]=r[cnt]=d[cnt]=0; return cnt; 
22 heap;
23 int n,now,a[N],root[N],L[N],R[N],tot[N];
24 long long ans;
25 int main()
26 
27     scanf("%d",&n);
28     for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]-=i;
29     for (int i=1;i<=n;i++)
30     
31         now++,root[now]=heap.new_heap(a[i]),tot[now]=1,L[now]=R[now]=i;
32         while (now>1&&heap.top(root[now-1])>heap.top(root[now]))
33         
34             now--,root[now]=heap.merge(root[now],root[now+1]),tot[now]+=tot[now+1],R[now]=R[now+1];
35             while (heap.size(root[now])*2>tot[now]+1) heap.pop(root[now]);
36         
37     
38     for (int i=1;i<=now;i++) for (int j=L[i],t=heap.top(root[i]);j<=R[i];j++) ans+=abs(a[j]-t);
39     printf("%lld",ans);
40 

 

以上是关于[可并堆] Bzoj P1367 sequence的主要内容,如果未能解决你的问题,请参考以下文章

可并堆试水--BZOJ1367: [Baltic2004]sequence

bzoj3011 可并堆

[BZOJ 2333] 棘手的操作 可并堆

BZOJ3252: 攻略 可并堆

bzoj2806 [Apio2012]dispatching可并堆

[BZOJ2809][Apio2012]dispatching 贪心+可并堆