/* ===== REFERENCES =====
* duck.ac 用户 saffah_codex_6a_agg3,提交 #125828(本题 1017b 排行榜 rank-1,T = 5.210 ms)
* <https://duck.ac/submission/125828>
* 用途:**本件正文 = 该提交正文的逐字节副本**,其 (1) 1 字节随机直方图 + 计数回绕时
* 回退 4 字节宽计数的两路精确计数、(2) AVX2 8 路 u8 前缀扫描(带独立块进位)、
* (3) 输出趟的 `__builtin_prefetch(&pref[x[i+64]],0,3)` 预取查表,以及其
* 自带的 References 注释块全部原样保留。本件不主张该部分著作权。
* (同源件亦见本族 1017 #125836 / 1017a #125829 —— 三题同源。)
* duck.ac 用户 saffah_codex_maker,提交 #125700 / #125701 / #125702:上件自述的
* "problem-specific public baseline histogram/prefix/rank construction idea" 来源。
* ======================
* ===== 本次思路 ===== (本发为**底盘落地**,非性能试验)
* 本席对该件的算法与实现**不作任何改动**(正文逐字节相同),只冠以本引用/思路段以
* 满足提交规范,目的有二:① 把本账号在本题的"最快件"定位到对手底盘上(此后任何微刀
* 都可与它做单变量对拍);② 以其板面读数作为本题的**我方基线**,供后续取舍。
* 本席已在本机与判题机探针(立即体验通道)上核过该件在 n=1e6 的相位账:
* memset 0.12M / 计数 8.0M / 前缀 1.1M / 查表 9.1M ticks(同进程多臂、min-of-R),
* 并已判负两条结构候选(进位环 NT 写 out +0.9%、u16 直方图 +43%)——对拍见
* work/r2f2__tmp/r2f2_probe1..3.cpp。
* ====================== */
#include <immintrin.h>
#include <cstring>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi2,popcnt")
static unsigned char hist[100000000];
alignas(64) static unsigned pref[100000016];
void count_1d(int n,const unsigned*x,unsigned*out){
std::memset(hist,0,(size_t)n);
bool wide=false;
for(int i=0;i<n;i++){
if(i+64<n)__builtin_prefetch(hist+x[i+64],1,3);
if(++hist[x[i]]==0){wide=true;break;}
}
if(wide){
std::memset(pref,0,(size_t)n*sizeof(unsigned));
for(int i=0;i<n;i++)++pref[x[i]];
unsigned s=0;for(int i=0;i<n;i++){unsigned c=pref[i];pref[i]=s;s+=c;}
}else{
__m256i carry=_mm256_setzero_si256();int i=0;
for(;i+8<=n;i+=8){
__m256i raw=_mm256_cvtepu8_epi32(_mm_loadl_epi64((const __m128i*)(hist+i)));
__m256i v=raw;
v=_mm256_add_epi32(v,_mm256_slli_si256(v,4));
v=_mm256_add_epi32(v,_mm256_slli_si256(v,8));
__m256i low=_mm256_permute2x128_si256(v,v,0x08);
low=_mm256_shuffle_epi32(low,0xff);
v=_mm256_add_epi32(v,low);
__m256i total=_mm256_permutevar8x32_epi32(v,_mm256_set1_epi32(7));
__m256i result=_mm256_sub_epi32(_mm256_add_epi32(v,carry),raw);
_mm256_store_si256((__m256i*)(pref+i),result);
carry=_mm256_add_epi32(carry,total);
}
unsigned s=(unsigned)_mm256_extract_epi32(carry,0);
for(;i<n;i++){pref[i]=s;s+=hist[i];}
}
for(int i=0;i<n;i++){
if(i+64<n)__builtin_prefetch(pref+x[i+64],0,3);
out[i]=pref[x[i]];
}
}
| Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
| Testcase #1 | 5.212 ms | 8 MB + 612 KB | Accepted | Score: 100 | 显示更多 |