1367: [Baltic2004]sequence
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1476 Solved: 606
[Submit][Status][Discuss]
Description
Input
Output
一个整数R
Sample Input
7
9
4
8
20
14
15
18
9
4
8
20
14
15
18
Sample Output
13
HINT
所求的Z序列为6,7,8,13,14,15,18.
R=13
/* 学长写的题解我并没有看懂,目前还处于蒙蔽状态 */ #include<iostream> #include<cstdio> #include<cstdlib> #define maxn 1000010 using namespace std; int t[maxn],root[maxn],l[maxn],r[maxn],num[maxn],cnt[maxn],n,tot; struct node{ int l,r,dis,w; }heap[maxn]; int merge(int a,int b){ if(!a||!b)return a+b; if(heap[a].w<heap[b].w)swap(a,b); heap[a].r=merge(heap[a].r,b); if(heap[heap[a].r].dis>heap[heap[a].l].dis) swap(heap[a].r,heap[a].l); if(!heap[a].r)heap[a].dis=0; else heap[a].dis=heap[heap[a].r].dis+1; return a; } int pop(int a){ return merge(heap[a].l,heap[a].r); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){scanf("%d",&t[i]);t[i]-=i;} for(int i=1;i<=n;i++){ tot++; l[tot]=r[tot]=i; num[tot]=cnt[tot]=1; root[tot]=i; heap[i].dis=heap[i].l=heap[i].r=0;//新建了一个堆 heap[i].w=t[i]; while(tot>1&&heap[root[tot]].w<heap[root[tot-1]].w){ tot--;//将两个堆合并 root[tot]=merge(root[tot],root[tot+1]); num[tot]+=num[tot+1]; cnt[tot]+=cnt[tot+1]; r[tot]=r[tot+1]; while(cnt[tot]*2>num[tot]+1){ root[tot]=pop(root[tot]); cnt[tot]--; } } } long long ans=0; for(int i=1;i<=tot;i++){ for(int j=l[i],w=heap[root[i]].w;j<=r[i];j++) ans+=abs(t[j]-w); } cout<<ans; return 0; }