码迷,mamicode.com
首页 > 编程语言 > 详细

基数排序的奇技淫巧

时间:2017-02-12 21:10:36      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:关键字   ges   mem   cat   class   for   int   tor   后缀数组   

  据说是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

 

基数排序的奇技淫巧

标签:关键字   ges   mem   cat   class   for   int   tor   后缀数组   

原文地址:http://www.cnblogs.com/Sakits/p/6391750.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!