zoukankan      html  css  js  c++  java
  • 【BZOJ-1367】sequence 可并堆+中位数

    1367: [Baltic2004]sequence

    Time Limit: 20 Sec  Memory Limit: 64 MB
    Submit: 932  Solved: 348
    [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

    Source

    Solution

    论文中的例题,非常吼啊....思想巧妙

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 1000100
    long long ans;
    int n,data[maxn],root[maxn],L[maxn],R[maxn],cnt[maxn],tot;
    struct LeftTreeNode
    {
        int sz,son[maxn][2],d[maxn],size[maxn],a[maxn];
    //    LeftTreeNode () 
    //        {
    //            sz=0;memset(son,0,sizeof(son));memset(size,0,sizeof(size));
    //            memset(cnt,0,sizeof(cnt));memset(a,0,sizeof(a));memset(d,0,sizeof(d));
    //        }
        int Merge(int x,int y)
            {
                if (!x) return y;
                if (!y) return x;
                if (a[x]<a[y]) swap(x,y);
                son[x][1]=Merge(son[x][1],y);
                size[x]=size[son[x][0]]+size[son[x][1]]+1;
                if (d[son[x][1]]>d[son[x][0]]) swap(son[x][0],son[x][1]);
                d[x]=d[son[x][1]]+1;
                return x;
            }
        int Push(int x)
            {
                a[++sz]=x; size[sz]=1;
                son[sz][0]=son[sz][1]=d[sz]=0;
                return sz;
            }
        int Pop(int x) {return Merge(son[x][0],son[x][1]);}
        int Top(int x) {return a[x];}
        int Size(int x) {return size[x];}
    }LTHeap;
    int main()
    {
        n=read();
        for (int i=1; i<=n; i++) data[i]=read()-i;
        for (int i=1; i<=n; i++)
            {
                tot++;
                root[tot]=LTHeap.Push(data[i]); cnt[tot]=1; L[tot]=R[tot]=i;
                while (tot>1 && LTHeap.Top(root[tot])<LTHeap.Top(root[tot-1]))
                    {
                        tot--;
                        root[tot]=LTHeap.Merge(root[tot],root[tot+1]); cnt[tot]+=cnt[tot+1]; R[tot]=R[tot+1];
                        while (LTHeap.Size(root[tot])*2>cnt[tot]+1) 
                            root[tot]=LTHeap.Pop(root[tot]);
                    }
            }
        for (int i=1; i<=tot; i++)
            for (int j=L[i],top=LTHeap.Top(root[i]); j<=R[i]; j++)
                ans+=abs(data[j]-top);
        printf("%lld
    ",ans);
        return 0;
    }

    被YveH发现了...

  • 相关阅读:
    protobuf配置与使用
    gvim配置
    html div+css做页面布局
    php info
    开源相关工具汇总
    mem 0908
    linux dd指令
    java面试(2)--大数据相关
    Java基础面试题(1)
    转自ruby迷: 使用Net::SSH和Net::SCP编写Linux服务器管理脚本
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5469217.html
Copyright © 2011-2022 走看看