zoukankan      html  css  js  c++  java
  • bzoj 1367: [Baltic2004]sequence

    1367: [Baltic2004]sequence

    Time Limit: 20 Sec  Memory Limit: 64 MB

    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

    详细证明请看IOI2005国家集训队论文  黄源河 

    https://wenku.baidu.com/view/20e9ff18964bcf84b9d57ba1.html

    两个极端情况:

    1、a[i]<a[i+1]<a[i+2]<a[i+3]……  ans[i]=a[i]

    2、a[i]>a[i+1]>a[i+2]>a[i+3]……  ans[i]=ans[i+1]=ans[i+2]=a[i+3]=区间中位数

    将每一个点看做一个区间,如果前一个区间的中位数比这个大,则合并

    所以我们对于每一段已求好的序列,既要维护它的中位数,又要支持合并

    因为我们合并的前提是:中位数(i)>中位数(i+1),那么对于合并后的i而言,中位数肯定是不升的

    根据这个性质我们又可以用可并堆了,堆顶元素表示该序列中的中位数

    当堆的元素个数*2>序列长度+1的时候就可以弹出堆顶

    如何保证严格上升?

    常用套路:a[i]-i

    #include<cstdio>
    #include<algorithm>
    #define N 1000001
    using namespace std;
    int a[N],siz[N],tot[N],root[N],lc[N],rc[N],now,lp[N],rp[N],dis[N];
    int merge(int x,int y)
    {
        if(!x) return y;
        if(!y) return x;
        if(a[x]<a[y]) swap(x,y);
        rc[x]=merge(rc[x],y);
        siz[x]=siz[lc[x]]+siz[rc[x]]+1;
        if(dis[lc[x]]<dis[rc[x]]) swap(lc[x],rc[x]);
        dis[x]=dis[rc[x]]+1;
        return x;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]-=i;
        for(int i=1;i<=n;i++)
        {
            root[++now]=i;
            lp[now]=rp[now]=i;
            siz[root[now]]=tot[now]=1;
            while(now>1&&a[root[now-1]]>a[root[now]])
            {
                now--;
                rp[now]=rp[now+1]; tot[now]+=tot[now+1];
                root[now]=merge(root[now],root[now+1]);
                while(siz[root[now]]*2>tot[now]+1)
                  root[now]=merge(lc[root[now]],rc[root[now]]);
            }
        }
        long long ans=0;
        for(int i=1;i<=now;i++)
         for(int j=lp[i];j<=rp[i];j++)
          ans+=abs((long long)a[j]-a[root[i]]);
        printf("%lld",ans);
    }
  • 相关阅读:
    一个案例
    Python Qt 简介
    【第二】用QtDesigner设计第一个界面
    【第一节】QtDesigner安装
    【第十二节】PyQt5俄罗斯方块
    【第十一节】PyQt5自定义控件
    【第十节】PyQt5绘图
    【第九节】PyQt 拖拽
    【第八节】PyQt5控件(II)
    【第七节】PyQt5控件
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6869859.html
Copyright © 2011-2022 走看看