Luogu 1177 - 【模板】快速排序 - [快速排序][归并排序][无旋Treap]

题目链接:https://www.luogu.org/problemnew/show/P1177

题意:输入 $n$ 以及后续 $n$ 个整数,让你将这 $n$ 个整数从小到大排序输出。

 

归并排序(用时: 121ms / 内存: 1568KB):

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+5;
int n,a[maxn],t[maxn];
void Merge(int l,int m,int r)
{
    int i=l,j=m+1;
    int k=l;
    while(i<=m && j<=r)
    {
        if(a[i]>a[j]) t[k++]=a[j++];
        else t[k++]=a[i++];
    }
    while(i<=m) t[k++]=a[i++];
    while(j<=r) t[k++]=a[j++];
    for(int i=l;i<=r;i++) a[i]=t[i];
}
void MergeSort(int l,int r)
{
    if(l<r)
    {
        int m=(l+r)>>1;
        MergeSort(l,m);
        MergeSort(m+1,r);
        Merge(l,m,r);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    MergeSort(1,n);
    for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');
}

 

快速排序(用时: 117ms / 内存: 1040KB):

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+5;
int n,a[maxn];
void QuickSort(int l,int r)
{
    int i=l, j=r, p=a[rand()%(r-l+1)+l];
    while(i<=j)
    {
        while(a[i]<p) i++;
        while(a[j]>p) j--;
        if(i<=j) swap(a[i],a[j]), i++, j--;
    }
    if(l<j) QuickSort(l,j);
    if(i<r) QuickSort(i,r);
}
int main()
{
    srand(5064860);

    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    QuickSort(1,n);
    for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');
}

(很久以前的https://www.cnblogs.com/dilthey/p/6804152.html这篇随笔里写的快排,选最后一个元素做pivot被卡了QAQ,换一个)

 

FHQ-Treap(用时: 260ms / 内存: 2824KB):

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

/******************************** FHQ Treap - st ********************************/
int root,nodecnt;
int ch[maxn][2];
int key[maxn],dat[maxn];
int siz[maxn];
int NewNode(int val)
{
    int x=++nodecnt;
    key[x]=val, dat[x]=rand();
    siz[x]=1, ch[x][0]=ch[x][1]=0;
    return x;
}
void Pushup(int x) {
    siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
void Init()
{
    root=nodecnt=0;
    key[0]=dat[0]=0;
    siz[0]=0, ch[0][0]=ch[0][1]=0;
}
void Split(int x,int k,int &a,int &b)
{
    if(x==0)
    {
        a=b=0;
        return;
    }
    if(key[x]<=k) a=x, Split(ch[x][1],k,ch[a][1],b);
    else b=x, Split(ch[x][0],k,a,ch[b][0]);
    Pushup(x);
}
void Merge(int &x,int a,int b)
{
    if(a==0 || b==0)
    {
        x=a+b;
        return;
    }
    if(dat[a]<dat[b]) x=a, Merge(ch[x][1],ch[a][1],b);
    else x=b, Merge(ch[x][0],a,ch[b][0]);
    Pushup(x);
}
/******************************** FHQ Treap - ed ********************************/

void Insert(int val)
{
    int a=0,b=0;
    Split(root,val,a,b);
    Merge(a,a,NewNode(val));
    Merge(root,a,b);
}
void Inorder(int rt)
{
    if(rt==0) return;
    Inorder(ch[rt][0]);
    printf("%d ",key[rt]);
    Inorder(ch[rt][1]);
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1,x;i<=n;i++)
    {
        scanf("%d",&x);
        Insert(x);
    }
    Inorder(root);
}

(FHQ-Treap真是好写又好用QAQ!)

posted @ 2019-01-07 23:21  Dilthey  阅读(235)  评论(0编辑  收藏  举报