提交记录 50303


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_v41_0919 1009a. 测测你的三维数点2 Accepted 100 40.28 ms 4736 KB C++17 5.88 KB
提交时间 评测时间
2026-09-19 16:36:25 2026-09-19 16:37:07
/* 3D dominance counting: out[i] = #{ j : x[j]<x[i] && y[j]<y[i] && z[j]<z[i] }.
 * CDQ over the x-sorted (time) axis split at x-group boundaries; merge by y;
 * Fenwick tree over z.  Base blocks (<=128) solved with an SSE2 brute force and
 * sorted by y with a bottom-up merge. */
#include <emmintrin.h>

typedef unsigned u32;

static int N;
static const u32 *PX;
static u32 *AY, *AZ;
static int *AO;
static u32 *TMPY, *TMPZ;
static int *TMPO;
static u32 *BIT;
static u32 *ANS;
static int *GSTART, *GNEXT;

static inline void bit_add(int i) { for (; i <= N; i += i & (-i)) BIT[i]++; }
static inline u32 bit_sum(int i) { u32 s = 0; for (; i > 0; i -= i & (-i)) s += BIT[i]; return s; }

static inline void sort_y(int l, int r) {
    for (int i = l + 1; i < r; i++) {
        u32 vy = AY[i], vz = AZ[i]; int vo = AO[i];
        int j = i - 1;
        while (j >= l && AY[j] > vy) { AY[j+1]=AY[j]; AZ[j+1]=AZ[j]; AO[j+1]=AO[j]; j--; }
        AY[j+1]=vy; AZ[j+1]=vz; AO[j+1]=vo;
    }
}

static void merge_sort_y(int l, int r) {
    int len = r - l;
    if (len < 2) return;
    if (len <= 16) { sort_y(l, r); return; }
    for (int w = 1; w < len; w <<= 1) {
        for (int s = l; s < r; s += (w << 1)) {
            int m = s + w; if (m > r) m = r;
            int e = s + (w << 1); if (e > r) e = r;
            if (m >= e) continue;
            int a = s, b = m, k = s;
            while (a < m && b < e) {
                if (AY[a] <= AY[b]) { TMPY[k]=AY[a]; TMPZ[k]=AZ[a]; TMPO[k]=AO[a]; a++; }
                else { TMPY[k]=AY[b]; TMPZ[k]=AZ[b]; TMPO[k]=AO[b]; b++; }
                k++;
            }
            while (a < m) { TMPY[k]=AY[a]; TMPZ[k]=AZ[a]; TMPO[k]=AO[a]; a++; k++; }
            while (b < e) { TMPY[k]=AY[b]; TMPZ[k]=AZ[b]; TMPO[k]=AO[b]; b++; k++; }
            for (k = s; k < e; k++) { AY[k]=TMPY[k]; AZ[k]=TMPZ[k]; AO[k]=TMPO[k]; }
        }
    }
}

#define BASE 128
#define PAD (BASE + 4)

static void cdq(int l, int r) {
    int len = r - l;
    if (len <= 1) return;
    if (len <= BASE) {
        u32 lx[PAD], ly[PAD], lz[PAD], lacc[PAD];
        int lo[PAD];
        int p4 = (len + 3) & ~3;
        for (int k = 0; k < p4; k++) {
            if (k < len) { int t = l + k; lx[k] = PX[AO[t]]; ly[k] = AY[t]; lz[k] = AZ[t]; lo[k] = AO[t]; }
            else { lx[k] = 0x7fffffff; ly[k] = 0x7fffffff; lz[k] = 0x7fffffff; lo[k] = 0; }
            lacc[k] = 0;
        }
        const __m128i one = _mm_set1_epi32(1);
        for (int a = 0; a < len; a++) {
            __m128i xa = _mm_set1_epi32((int)lx[a]);
            __m128i ya = _mm_set1_epi32((int)ly[a]);
            __m128i za = _mm_set1_epi32((int)lz[a]);
            for (int b = a + 1; b < p4; b += 4) {
                __m128i bx = _mm_loadu_si128((const __m128i *)(lx + b));
                __m128i by = _mm_loadu_si128((const __m128i *)(ly + b));
                __m128i bz = _mm_loadu_si128((const __m128i *)(lz + b));
                __m128i m = _mm_and_si128(_mm_cmplt_epi32(xa, bx), _mm_cmplt_epi32(ya, by));
                m = _mm_and_si128(m, _mm_cmplt_epi32(za, bz));
                m = _mm_and_si128(m, one);
                __m128i acc = _mm_loadu_si128((const __m128i *)(lacc + b));
                _mm_storeu_si128((__m128i *)(lacc + b), _mm_add_epi32(acc, m));
            }
        }
        for (int k = 0; k < len; k++) ANS[lo[k]] += lacc[k];
        merge_sort_y(l, r);
        return;
    }
    if (GSTART[l] == GSTART[r - 1]) { merge_sort_y(l, r); return; }
    int mid = (l + r) >> 1;
    {
        int gs = GSTART[mid];
        int c1 = gs, c2 = GNEXT[gs];
        int h = (l + r) >> 1;
        int d1 = (c1 > l && c1 < r) ? (c1 > h ? c1 - h : h - c1) : 0x7fffffff;
        int d2 = (c2 > l && c2 < r) ? (c2 > h ? c2 - h : h - c2) : 0x7fffffff;
        mid = (d1 <= d2) ? c1 : c2;
    }
    if (mid <= l || mid >= r) { merge_sort_y(l, r); return; }

    cdq(l, mid);
    cdq(mid, r);

    int a = l;
    for (int j = mid; j < r; j++) {
        u32 yj = AY[j];
        while (a < mid && AY[a] < yj) { bit_add((int)AZ[a] + 1); a++; }
        ANS[AO[j]] += bit_sum((int)AZ[j]);
    }
    for (int k = l; k < a; k++) { int i = (int)AZ[k] + 1; for (; i <= N; i += i & (-i)) BIT[i]--; }

    int i = l, k = l, m = mid;
    while (i < mid && m < r) {
        if (AY[i] <= AY[m]) { TMPY[k]=AY[i]; TMPZ[k]=AZ[i]; TMPO[k]=AO[i]; i++; }
        else { TMPY[k]=AY[m]; TMPZ[k]=AZ[m]; TMPO[k]=AO[m]; m++; }
        k++;
    }
    while (i < mid) { TMPY[k]=AY[i]; TMPZ[k]=AZ[i]; TMPO[k]=AO[i]; i++; k++; }
    while (m < r) { TMPY[k]=AY[m]; TMPZ[k]=AZ[m]; TMPO[k]=AO[m]; m++; k++; }
    for (k = l; k < r; k++) { AY[k]=TMPY[k]; AZ[k]=TMPZ[k]; AO[k]=TMPO[k]; }
}

void count_3d(int n, const unsigned *x, const unsigned *y, const unsigned *z, unsigned *out) {
    N = n; PX = x;
    if (n <= 0) return;
    static u32 *buf = 0;
    if (!buf || (int)buf[0] < n) {
        delete[] buf;
        size_t words = (size_t)n * 8 + 4 * n + 16;
        buf = new u32[words];
        buf[0] = n;
        AY = buf + 1;
        AZ = AY + n;
        TMPY = AZ + n;
        TMPZ = TMPY + n;
        BIT = TMPZ + n;
        ANS = BIT + n + 1;
        AO = (int *)(ANS + n);
        TMPO = AO + n;
        GSTART = TMPO + n;
        GNEXT = GSTART + n;
    }
    u32 *cnt = (u32 *)(GNEXT + n + 1);
    for (int i = 0; i <= n; i++) cnt[i] = 0;
    for (int i = 0; i < n; i++) cnt[x[i]]++;
    u32 s = 0;
    for (int v = 0; v <= n; v++) { u32 c = cnt[v]; cnt[v] = s; s += c; }
    for (int i = 0; i < n; i++) { int p = (int)cnt[x[i]]++; AY[p] = y[i]; AZ[p] = z[i]; AO[p] = i; }
    for (int i = 0; i <= n; i++) BIT[i] = 0;
    for (int i = 0; i < n; i++) ANS[i] = 0;
    {
        int t = 0;
        while (t < n) {
            u32 xv = PX[AO[t]];
            int e = t;
            while (e < n && PX[AO[e]] == xv) e++;
            for (int k = t; k < e; k++) GSTART[k] = t;
            GNEXT[t] = e;
            t = e;
        }
        GNEXT[n] = n;
    }
    cdq(0, n);
    for (int t = 0; t < n; t++) out[AO[t]] = ANS[AO[t]];
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #140.28 ms4 MB + 640 KBAcceptedScore: 100


Judge Duck Online | 评测鸭在线
Server Time: 2026-09-22 17:17:16 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠