首页 > 代码库 > 基数排序的奇技淫巧

基数排序的奇技淫巧

  据说是WC T2的子任务,ai<=2^32-1的基数排序,那么就把一个数分成几段多关键字基数排序就行了,类似后缀数组?

  分成8位/8位/8位/8位比分成16位/16位要快【丧病的底层优化

代码如下:

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[100001],b[100001],c[100001],d[100001],sa[100001],sa2[100001],sa3[100001],sa4[100001],sum[257],n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]>>16&((1<<8)-1),c[i]=a[i]>>8&((1<<8)-1),d[i]=a[i]&((1<<8)-1);
    for(int i=1;i<=n;i++)sum[d[i]]++;
    for(int i=1;i<=256;i++)sum[i]+=sum[i-1];
    for(int i=n;i>=1;i--)sa4[sum[d[i]]]=i,sum[d[i]]--;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)sum[c[i]]++;
    for(int i=1;i<=256;i++)sum[i]+=sum[i-1];
    for(int i=n;i>=1;i--)sa3[sum[c[sa4[i]]]]=sa4[i],sum[c[sa4[i]]]--;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)sum[b[i]]++;
    for(int i=1;i<=256;i++)sum[i]+=sum[i-1];
    for(int i=n;i>=1;i--)sa2[sum[b[sa3[i]]]]=sa3[i],sum[b[sa3[i]]]--;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)sum[a[i]>>16]++;
    for(int i=1;i<=256;i++)sum[i]+=sum[i-1];
    for(int i=n;i>=1;i--)sa[sum[a[sa2[i]]>>16]]=sa2[i],sum[a[sa2[i]]>>16]--;
    for(int i=1;i<=n;i++)printf("%d ",a[sa[i]]);
}
View Code

 

基数排序的奇技淫巧