提交记录 53086


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_v41_0919 1011a. 测测你的五维数点2 Accepted 100 2.449 s 17128 KB C++17 3.53 KB
提交时间 评测时间
2026-09-19 18:20:51 2026-09-19 18:20:55
// KD-dimensional strict dominance counting, n <= 100000, coordinates in [0,n).
// For each dimension d, points are ordered by rank; PB[d][b] is the bitset of the
// first b*K points of that order (a subset of the strict-smaller set of any point
// whose rank lies beyond b*K).  The answer is |AND_d PB[d][rank_d(i)/K]| plus the
// points inside the K-sized partial ranges of each dimension (deduplicated), which
// is exact because every point with a smaller rank either is in all the prefixes or
// falls into one of those partial ranges.
#include <cstdlib>
#include <cstring>
typedef unsigned u32;
typedef unsigned long long u64;

#define KD 5
#define NMAX 100000
#define K 512
#define WMAX ((NMAX + 63) / 64)
#define NB (NMAX / K + 2)

static int ORD[KD][NMAX];
static u32 RK[KD][NMAX];
static int STAMP[NMAX];
static u64 *PB;                     // [KD][NB][WMAX]
static u64 acc[WMAX], tmp[WMAX];

#define PBat(d, b) (PB + (((size_t)(d) * NB + (b)) * WMAX))

static void buildAll(int n, const unsigned *x[KD]) {
    int *cnt = (int *)malloc((size_t)(n + 1) * sizeof(int));
    for (int d = 0; d < KD; d++) {
        memset(cnt, 0, (size_t)(n + 1) * sizeof(int));
        for (int i = 0; i < n; i++) cnt[x[d][i] + 1]++;
        for (int v = 1; v <= n; v++) cnt[v] += cnt[v - 1];
        for (int i = 0; i < n; i++) ORD[d][cnt[x[d][i]]++] = i;
        // rank of point j = number of points with a strictly smaller coordinate
        for (int p = 0; p < n; ) {
            int q = p;
            unsigned val = x[d][ORD[d][p]];
            while (q < n && x[d][ORD[d][q]] == val) q++;
            for (int t = p; t < q; t++) RK[d][ORD[d][t]] = (u32)p;
            p = q;
        }
    }
    free(cnt);
    // prefix bitsets: PB[d][b] = points at positions [0, b*K) of order d
    int words = (n + 63) >> 6;
    u64 *cur = (u64 *)calloc((size_t)words, 8);
    for (int d = 0; d < KD; d++) {
        memset(cur, 0, (size_t)words * 8);
        memset(PBat(d, 0), 0, (size_t)words * 8);
        for (int p = 0; p < n; p++) {
            if (p && (p % K) == 0) memcpy(PBat(d, p / K), cur, (size_t)words * 8);
            int j = ORD[d][p];
            cur[j >> 6] |= 1ULL << (j & 63);
        }
    }
    free(cur);
}

static void solve(int n, const unsigned *x[KD], unsigned *out) {
    static u64 *allocated = 0;
    if (!allocated) {
        allocated = (u64 *)calloc((size_t)KD * NB * WMAX, 8);
        PB = allocated;
    }
    buildAll(n, x);
    int words = (n + 63) >> 6;
    memset(STAMP, 0, (size_t)n * sizeof(int));
    int stampCur = 0;
    for (int i = 0; i < n; i++) {
        int b0 = (int)(RK[0][i] / K);
        memcpy(acc, PBat(0, b0), (size_t)words * 8);
        for (int d = 1; d < KD; d++) {
            u64 *pd = PBat(d, RK[d][i] / K);
            for (int w = 0; w < words; w++) acc[w] &= pd[w];
        }
        u32 ans = 0;
        for (int w = 0; w < words; w++) ans += (u32)__builtin_popcountll(acc[w]);
        stampCur++;
        for (int d = 0; d < KD; d++) {
            int lo = (int)(RK[d][i] / K) * K, hi = (int)RK[d][i];
            for (int p = lo; p < hi; p++) {
                int j = ORD[d][p];
                if (STAMP[j] == stampCur) continue;
                STAMP[j] = stampCur;
                int ok = 1;
                for (int e = 0; e < KD; e++) if (RK[e][j] >= RK[e][i]) { ok = 0; break; }
                if (ok) ans++;
            }
        }
        out[i] = ans;
    }
}

#if KD == 4
void count_4d(int n, const unsigned *x[4], unsigned *out) { solve(n, x, out); }
#else
void count_5d(int n, const unsigned *x[5], unsigned *out) { solve(n, x, out); }
#endif

CompilationN/AN/ACompile OKScore: N/A

Testcase #12.449 s16 MB + 744 KBAcceptedScore: 100


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