首页 > 其他 > 详细

[BZOJ1367] [Baltic2004]sequence

时间:2018-08-25 13:03:41      阅读:132      评论:0      收藏:0      [点我收藏+]

[BZOJ1367] [Baltic2004]sequence

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

试题分析

因为绝对值符号一般涉及到中位数的介入,所以我们先将\(a_i=a_i-i\),这样可以将\(b_i<b_{i+1}\)转化成\(b_i\leq b_{i+1}\)
\(a_1\leq a_2\leq \ldots\leq a_n\)的时候,显然取\(b_i =a_i\)最优。
\(a_1>a_2>\ldots>a_n\)的时候,取中位数最优。
我们先将这个最优的解大致构造出来再考虑调整。
显然当取\(b_i=a_i\)最优,那么如果存在\(b_i>b_{i+1}\)怎么办呢?
根据上面的推论,由于一段数最优的是中位数,所以只会把\(b_i\)\(b_{i+1}\)这两段合并。
那么我们用可并堆维护合并的中位数即可。

BZOJ空间太小了吧

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
 
using namespace std;
#define LL long long
 
inline LL read(){
    LL x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const LL INF = 2147483600;
const LL MAXN = 1100000;
 
int N; int t[MAXN+1];
 
struct Heap{
    int l[MAXN+1],r[MAXN+1]; int val[MAXN+1],sz[MAXN+1];
    int rt[MAXN+2],dis[MAXN+1]; int cnt; bool c;
    inline LL merge(LL x,LL y){
        if(!x||!y) return x|y;
        if(c^(val[x]<val[y])) swap(x,y);
        r[x]=merge(r[x],y);
        if(dis[l[x]]<dis[r[x]]) swap(l[x],r[x]);
        dis[x]=dis[r[x]]+1; return x;
    }
    inline void pop(LL x){
        rt[x]=merge(l[rt[x]],r[rt[x]]); sz[x]--; return ;
    }
    inline void insert(LL x,LL y){
        rt[N+1]=++cnt; l[cnt]=r[cnt]=0; val[cnt]=y;
        rt[x]=merge(rt[x],rt[N+1]);  sz[x]++; return ; 
    }
}mx,mi;
inline LL Get(LL x){
    if(!x) return 0;
    while(mx.sz[x]<mi.sz[x]){
        LL v=mi.val[mi.rt[x]];
        mi.pop(x); mx.insert(x,v);
    }
    while(mx.sz[x]-mi.sz[x]>1){
        LL v=mx.val[mx.rt[x]];
        mx.pop(x); mi.insert(x,v);
    }
    if(!mi.sz[x]) return mx.val[mx.rt[x]];
    return mx.val[mx.rt[x]];
} int las[MAXN+1],L[MAXN+1],R[MAXN+1];
 
int main(){
    N=read(); mx.c=0; mi.c=1;
    for(LL i=1;i<=N;i++){
        t[i]=read(),t[i]-=i;
    } LL cnt=0,Las=0;
    for(LL i=1;i<=N;i++){
        ++cnt; mx.insert(cnt,t[i]); las[cnt]=Las;
        L[cnt]=i;
        R[cnt]=i; Las=cnt; LL cntx=cnt;
        while(cntx&&Get(cntx)<Get(las[cntx])){
            mx.sz[las[cntx]]+=mx.sz[cntx];
            mx.merge(mx.rt[las[cntx]],mx.rt[cntx]); 
            mi.sz[las[cntx]]+=mi.sz[cntx];
            mi.merge(mi.rt[las[cntx]],mi.rt[cntx]);
            Get(las[cntx]);
            R[las[cntx]]=R[cntx]; Las=las[cntx]; cntx=las[cntx];
        }
    } LL ans=0;
    for(LL i=Las;i;i=las[i]){
        LL mid=Get(i);
        for(LL j=L[i];j<=R[i];j++)
            ans+=max(t[j]-mid,mid-t[j]);
    } printf("%lld\n",ans);
    return 0;
}

[BZOJ1367] [Baltic2004]sequence

原文:https://www.cnblogs.com/wxjor/p/9533173.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!