Luogu P5715 三位数排序

Posted luoshui-tianyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P5715 三位数排序相关的知识,希望对你有一定的参考价值。

Luogu P5715 三位数排序

静态查询区间第$k$小数——主席树板子题!
直接上板子即可。

#include<bits/stdc++.h>
#define N 200010
#define mid ((l+r)>>1)

using namespace std;

int n,m,l,r,k,ans,id,siz;
int a[N],b[N];

struct segmenttree {
    int ls,rs,sum,root;
}tree[N*40];

void Build(int &o,int l,int r) {
    id++;
    o=id;
    tree[o].sum=0;
    if(l==r) {
        return;
    }
    Build(tree[o].ls,l,mid);
    Build(tree[o].rs,mid+1,r);
    return;
}

void Update(int &o,int l,int r,int pre,int x) {
    id++;
    o=id;
    tree[o].ls=tree[pre].ls;
    tree[o].rs=tree[pre].rs;
    tree[o].sum=tree[pre].sum+1;
    if(l==r) {
        return;
    }
    if(x<=mid) {
        Update(tree[o].ls,l,mid,tree[pre].ls,x);
    }
    else {
        Update(tree[o].rs,mid+1,r,tree[pre].rs,x);
    }
    return;
}

int Find(int x,int y,int l,int r,int k) {
    if(l==r) {
        return l;
    }
    int cnt=tree[tree[y].ls].sum-tree[tree[x].ls].sum;
    if(k<=cnt) {
        return Find(tree[x].ls,tree[y].ls,l,mid,k);
    }
    else {
        return Find(tree[x].rs,tree[y].rs,mid+1,r,k-cnt);
    }
}

int main()
{
    n=3,m=3;
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    siz=unique(b+1,b+n+1)-b-1;
    Build(tree[0].root,1,siz);
    for(int i=1;i<=n;i++) {
        int val=lower_bound(b+1,b+siz+1,a[i])-b;
        Update(tree[i].root,1,siz,tree[i-1].root,val);
    }
    l=1,r=n;
    for(int i=1;i<=m;i++) {
        k=i;
        ans=Find(tree[l-1].root,tree[r].root,1,siz,k);
        printf("%d ",b[ans]);
    }
    return 0;
}

以上是关于Luogu P5715 三位数排序的主要内容,如果未能解决你的问题,请参考以下文章

Luogu 1008 三连击

php+mysql,把三个数字按从小到大排序变成一个三位数

excel表格中的数字有一位数、两位数、三位数,可是排序只按第一位数排,怎样才能按1到10000的自然顺序排呢

Luogu2839 Middle 主席树二分答案

三位数排序输出

(luogu题解搬运系列)luogu p1459 三值的排序