首页 > 代码库 > 【bzoj1367】[Baltic2004]sequence 可并堆
【bzoj1367】[Baltic2004]sequence 可并堆
题目描述
输入
输出
一个整数R
样例输入
7
9
4
8
20
14
15
18
样例输出
13
题解
可并堆,黄源河《左偏树的特点及其应用》Page 13例题原题
#include <cstdio>#include <cstring>#include <algorithm>#define N 1000010using namespace std;int a[N] , root[N] , l[N] , r[N] , d[N] , w[N] , tot , si[N] , lp[N] , rp[N];int merge(int x , int y){ if(!x) return y; if(!y) return x; if(w[x] < w[y]) swap(x , y); si[x] += si[y]; r[x] = merge(r[x] , y); if(d[l[x]] < d[r[x]]) swap(l[x] , r[x]); d[x] = d[r[x]] + 1; return x;}int main(){ int n , i , j , p = 0; long long ans = 0; scanf("%d" , &n); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , a[i] -= i; for(i = 1 ; i <= n ; i ++ ) { root[++p] = ++tot , w[tot] = a[i] , si[tot] = 1 , lp[p] = rp[p] = i; while(p > 1 && w[root[p]] < w[root[p - 1]]) { p -- , root[p] = merge(root[p] , root[p + 1]) , rp[p] = rp[p + 1]; while(2 * si[root[p]] > rp[p] - lp[p] + 2) root[p] = merge(l[root[p]] , r[root[p]]); } } for(i = 1 ; i <= p ; i ++ ) for(j = lp[i] ; j <= rp[i] ; j ++ ) ans += (long long)abs(w[root[i]] - a[j]); printf("%lld\n" , ans); return 0;}
【bzoj1367】[Baltic2004]sequence 可并堆
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。