# BZOJ 1367: [Baltic2004]sequence [可并堆 中位数]

## 1367: [Baltic2004]sequence

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 1111  Solved: 439
[Submit][Status][Discuss]

7
9
4
8
20
14
15
18

13

## HINT

R=13

<好烦啊先不管了

rt[]保存了每个区间用的左偏树的根

<变成<=用到了常见技巧 -i

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc t[x].l
#define rc t[x].r
typedef long long ll;
const int N=1e6+5,INF=1e9;
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n,a[N];
struct node{
int l,r,v,d,size;
node(){l=r=v=d=size=0;}
}t[N];
int sz;
int Merge(int x,int y){
if(x==0||y==0) return x|y;
if(t[x].v<t[y].v) swap(x,y);
rc=Merge(rc,y);
t[x].size=t[lc].size+t[rc].size+1;
if(t[lc].d<t[rc].d) swap(lc,rc);
t[x].d=t[rc].d+1;
return x;
}
inline int nw(int v){
t[++sz].v=v;
t[sz].size=1;
return sz;
}
inline int top(int x){return t[x].v;}
inline int size(int x){return t[x].size;}
inline void pop(int &x){x=Merge(lc,rc);}
ll ans;
int rt[N],p,l[N],r[N],tot[N];
void solve(){
for(int i=1;i<=n;i++){
rt[++p]=nw(a[i]);
l[p]=r[p]=i;tot[p]=1;
while(p-1&&top(rt[p-1])>top(rt[p])){
rt[p-1]=Merge(rt[p-1],rt[p]);
p--;
r[p]=i;
while(size(rt[p])>(r[p]-l[p]+2)/2) pop(rt[p]);
}
}
for(int i=1;i<=p;i++)
for(int j=l[i];j<=r[i];j++) ans+=abs(a[j]-top(rt[i]));
printf("%lld",ans);
}

int main(){
//freopen("in.txt","r",stdin);
t[0].d=-1;
solve();
return 0;
}