• 51Nod1364 最大字典序排列


    题目看这里

    一道比较简单的贪心题

    容易想到从前到后确定每一位

    我们可以用一个splay来维护当前未确定的部分的顺序

    假设当前剩下k次操作机会

    那么我们可以求出splay中前k+1个元素中的最大元素i,令k减少rank(i),让后将其输出并从splay中删掉

    最后k=0时,输出splay中剩余元素

    比题解那个线段树好写多了,主要是不用想,而且splay还挺快的

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 100010
    #define son(x) (s[f[x]][1]==x)
    using namespace std;
    int f[N],s[N][2],sz[N],l[N],t[N];
    int n,k,cnt=0,rt=0;
    inline int ps(int x){
        sz[x]=sz[s[x][0]]+sz[s[x][1]]+1;
        t[x]=max(l[x],max(t[s[x][0]],t[s[x][1]]));
    }
    inline void rot(int x){
        int p=f[x],g=f[p],d=son(x);
        s[p][d]=s[x][!d]; f[s[p][d]]=p;
        s[x][!d]=p; f[p]=x; f[x]=g;
        if(g) s[g][p==s[g][1]]=x; ps(p); ps(x);
    }
    inline void splay(int x,int r=0){
        for(int p;(p=f[x])!=r;rot(x))
            if(f[p]!=r && son(x)==son(p)) rot(p);
        if(!r) rt=x;
    }
    inline int select(int k,int x=rt){
        for(int w;;){
            w=sz[s[x][0]]+1;
            if(w==k) return x;
            if(k<w) x=s[x][0];
            else k-=w,x=s[x][1];
        }
    }
    inline int rank(int x){
        int r=sz[s[x][0]]+1;
        for(;x;x=f[x])
            if(son(x)) r+=sz[s[f[x]][0]]+1;
        return r;
    }
    inline int merge(int x,int y){
        if(x&&y){
            y=select(1,y);
            splay(y,rt);
            s[y][0]=x; f[x]=y; ps(y);
            return y;
        } return x+y;
    }
    inline int fMax(int x){
        for(;;){
            if(l[x]==t[x]) return x;
            else if(t[s[x][0]]>t[s[x][1]]) x=s[x][0]; else x=s[x][1];
        }
    }
    int main(){
        scanf("%d%d",&n,&k);
        for(int x,i=1;i<=n;++i){
            scanf("%d",l+i);
            if(i>1){ f[i-1]=i; s[i][0]=i-1; ps(i); } else sz[i]=1,ps(i);
        }
        rt=n;
        for(int i=1,j;k>0&&i<=n;++i){
            splay(select(min(k+1,sz[rt])));
            if(l[rt]>t[s[rt][0]]) j=rt;
            else splay(fMax(s[rt][0]));
            printf("%d
    ",l[rt]); k-=sz[s[rt][0]]; rt=merge(s[rt][0],s[rt][1]); f[rt]=0;
        }
        while(sz[rt]) splay(select(1)),printf("%d
    ",l[rt]),rt=merge(s[rt][0],s[rt][1]),f[rt]=0;;
    }

  • 相关阅读:
    Qt 任务调度器
    我又回来了,行情好转。
    设置IIS7文件上传的最大大小 maxAllowedContentLength,maxRequestLength
    ckfinder 1
    Oracle 数据库备份还原(Expdp/impdp)记录
    vs2015 去除 git 源代码 绑定
    java 核心技术之多线程篇
    java 核心技术之基础篇(三)
    java核心技术之基础篇(二)
    java 核心技术之基础篇(一)
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477087.html
Copyright © 2020-2023  润新知