【简介】
计数排序的时间复杂度是O(n+m)的,n为元素个数,m为桶的大小。
从低位到高位的方法可以加快速度(卡常数)。
分块分为3块最好了(利用CPU三级缓存的原理)
这样1e的数据可以卡到2秒左右。
WC2017 T2真是丧心病狂。
【代码】
#include <ctime>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma GCC optimize(2)
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 100000005
int a[maxn+15],n;
const int base2=32767,base3=1023;
int top=0;
int hash[base2+15],res[maxn+15];
int hash2[base3+15],res2[maxn+15];
vector <int> v[base2+15];
int main()
{
n=maxn;
F(i,1,n) a[i]=(rand()%30000)*(rand()%30000);
// int k1=clock(),k2;
/*
for (int i=1;i<=n;++i) v[a[i]&base2].push_back(a[i]);
top=0;
F(i,0,32767)
{
for (int j=0;j<v[i].size();++j) a[++top]=v[i][j];
v[i].clear();
}
for (int i=1;i<=n;++i) v[(a[i]>>15)&base2].push_back(a[i]);
top=0;
F(i,0,32767) for (int j=0;j<v[i].size();++j) a[++top]=v[i][j];
*/ //6s
/*
F(i,1,n) ++hash[a[i]&base2];
F(i,1,base2) hash[i]+=hash[i-1];
D(i,n,1)
{
res[hash[a[i]&base2]--]=a[i];
}
memcpy(a,res,(n+1)*sizeof (int));
memset(hash,0,sizeof hash);
F(i,1,n) ++hash[(a[i]>>15)&base2];
F(i,1,base2) hash[i]+=hash[i-1];
D(i,n,1) res[hash[(a[i]>>15)&base2]--]=a[i];
memcpy(a,res,(n+1)*sizeof (int));
k2=clock();
printf("%d %d\n",k1,k2);
*/ //2.3s
F(i,1,n) ++hash2[a[i]&base3];
F(i,1,base3) hash2[i]+=hash2[i-1];
D(i,n,1) res2[hash2[a[i]&base3]--]=a[i];
memcpy(a,res2,(n+1)*sizeof (int));
memset(hash2,0,sizeof hash2);
F(i,1,n) ++hash2[(a[i]>>10)&base3];
F(i,1,base3) hash2[i]+=hash2[i-1];
D(i,n,1) res2[hash2[(a[i]>>10)&base3]--]=a[i];
memcpy(a,res2,(n+1)*sizeof (int));
memset(hash2,0,sizeof hash2);
F(i,1,n) ++hash2[(a[i]>>20)&base3];
F(i,1,base3) hash2[i]+=hash2[i-1];
D(i,n,1) res2[hash2[(a[i]>>20)&base3]--]=a[i];
memcpy(a,res2,(n+1)*sizeof (int));
//1.8s O2: 1.1s
// k2=clock();
// printf("%d %d\n",k1,k2);
F(i,1,n) printf("%d%c",a[i],i==n?‘\n‘:‘ ‘);
}
原文:http://www.cnblogs.com/SfailSth/p/6387987.html