首页 > 代码库 > [bzoj 1367][Baltic2004]sequence

[bzoj 1367][Baltic2004]sequence

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1367

[Baltic2004]sequence

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 1304  Solved: 531
[Submit][Status][Discuss]

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

对于严格递增的序列,只要选的和原来的数列一样就是最优的。

对于严格递减的序列,只有选时原来数列的中位数的数就是最优的(证明过程跟传递糖果差不多,就是转化成数轴上的最短距离和)

这样我们可以把数列化成部分递增,部分递减,分别贪心处理,当然这个过程中需要可并堆维护中位数。

 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1000005; 4 typedef long long ll; 5 int read(){ 6     int rt=0,fl=1;char ch=getchar(); 7     while(ch<0||ch>9){if(ch==-)fl=-1;ch=getchar();} 8     while(ch>=0&&ch<=9){rt=rt*10+ch-0;ch=getchar();} 9     return rt*fl;10 }11 ll ans;12 int n,now;13 int a[maxn],root[maxn];14 int L[maxn],R[maxn],tot[maxn];15 struct Tr{16     int cnt;17     int l[maxn],r[maxn];18     ll v[maxn];int sz[maxn],d[maxn];19     int merge(int x,int y){20         if(x==0||y==0)return x+y;21         if(v[x]<v[y])swap(x,y);22         r[x]=merge(r[x],y);23         sz[x]=sz[l[x]]+sz[r[x]]+1;24         if(d[r[x]]>d[l[x]])swap(l[x],r[x]);25         d[x]=d[r[x]]+1;26         return x;27     }28     int top(int x){29         return v[x];30     }31     int size(int x){32         return sz[x];33     }34     void pop(int &x){35         x=merge(l[x],r[x]);36     }37     int Create(ll x){38         v[++cnt]=x;39         sz[cnt]=1;40         l[cnt]=r[cnt]=d[cnt]=0;41         return cnt;42     }43 }heap;44 int main(){45     n=read();46     for(int i=1;i<=n;i++)a[i]=read()-i;47     for(int i=1;i<=n;i++){48         now++;49         root[now]=heap.Create(a[i]);50         tot[now]=1;51         L[now]=R[now]=i;52         while(now>1 && heap.top(root[now-1])>heap.top(root[now])){53             now--;54             root[now]=heap.merge(root[now+1],root[now]);55             tot[now]+=tot[now+1];R[now]=R[now+1];56             while(heap.size(root[now])*2>tot[now]+1)57                 heap.pop(root[now]);58         }59     }60     for(int i=1;i<=now;i++)61         for(int j=L[i],t=heap.top(root[i]);j<=R[i];j++)62             ans+=abs(a[j]-t);63     printf("%lld",ans);64 }

 

[bzoj 1367][Baltic2004]sequence