提交记录 53380


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_v41_0919 noi17a. 【NOI2017】整数 Accepted 100 543.299 ms 4772 KB C++17 11.71 KB
提交时间 评测时间
2026-09-19 19:06:21 2026-09-19 19:06:39
#define DUMPIDX 0
// noi17a 【NOI2017】整数  (fast)
// x stored as base-2^30 digits; block (64 digit) summaries for "next non-full /
// next non-zero digit" give amortised O(1) per carry run.
#include <cstdio>
#include <cstring>
#include <cstdlib>

typedef unsigned long long u64;
typedef unsigned int u32;

#ifdef TEST_IO
static const char *IN; static u64 INSZ; static char *OUT; static u64 OUTSZ = 0; static u64 OUTLIM = 1u<<28;
#else
struct DI { u64 abi; const char*in; u64 insz; char*out; u64 outlim; u64 outsz; char*err;
            u64 errlim; u64 errsz; const char*IB; u64 IBlim; char*OB; u64 OBlim; u64 tscfreq; }
            __attribute__((packed));
#define DUCKINFO 0x243FFF90ULL
static struct DI *di;
static const char *IN; static u64 INSZ; static char *OUT; static u64 OUTSZ = 0; static u64 OUTLIM;
#endif

static const u32 MASK = (1u << 30) - 1u;
static const int MAXD = 1000104;
static const int NB = MAXD / 64 + 2;          // 15627
static const int NC = NB / 64 + 2;            // 246

static u32 dg[MAXD];
static unsigned char blkState[NB];   // 0 normal, 1 all-zero, 2 all-MASK
static unsigned char supState[NC];   // lazy whole c-entry (64 blocks = 4096 digits)
static u64 blkFull[NB], blkZero[NB];
static u64 cFull[NC], cZero[NC];

static inline void updBlockC(int g) {
    int c = g >> 6; u64 bit = 1ULL << (g & 63);
    if (blkFull[g] == ~0ULL) cFull[c] |= bit; else cFull[c] &= ~bit;
    if (blkZero[g] == ~0ULL) cZero[c] |= bit; else cZero[c] &= ~bit;
}
static inline void updDigit(int p) {
    u32 v = dg[p];
    int g = p >> 6; u64 bit = 1ULL << (p & 63);
    if (v == MASK) blkFull[g] |= bit; else blkFull[g] &= ~bit;
    if (v == 0) blkZero[g] |= bit; else blkZero[g] &= ~bit;
    updBlockC(g);
}

static inline void setBlockAll(int g, int allOnes) {
    if (allOnes) { blkFull[g] = ~0ULL; blkZero[g] = 0ULL; }
    else { blkFull[g] = 0ULL; blkZero[g] = ~0ULL; }
    updBlockC(g);
}
static inline void materialize(int g) {
    unsigned char st = blkState[g];
    if (!st) return;
    u32 v = (st == 1) ? 0u : MASK;
    u32 *q = dg + (g << 6);
    for (int i = 0; i < 64; i++) q[i] = v;
    blkState[g] = 0;
}
static inline u64 validMaskBlocks(int c) {
    int lo = c * 64, hi = lo + 64;
    if (hi > NB) hi = NB;
    if (hi <= lo) return 0ULL;
    int n = hi - lo;
    return (n >= 64) ? ~0ULL : ((1ULL << n) - 1ULL);
}
static inline void materializeSuper(int c) {
    unsigned char st = supState[c];
    if (!st) return;
    int lo = c * 64, hi = lo + 64;
    if (hi > NB) hi = NB;
    for (int g = lo; g < hi; g++) {
        blkState[g] = st;
        if (st == 2) { blkFull[g] = ~0ULL; blkZero[g] = 0ULL; }
        else { blkFull[g] = 0ULL; blkZero[g] = ~0ULL; }
    }
    u64 vm = validMaskBlocks(c);
    if (st == 2) { cFull[c] = vm; cZero[c] = 0ULL; }
    else { cFull[c] = 0ULL; cZero[c] = vm; }
    supState[c] = 0;
}
static inline u32 getDigit(int p) {
    int g = p >> 6;
    if (supState[g >> 6]) materializeSuper(g >> 6);
    if (blkState[g]) materialize(g);
    return dg[p];
}
static inline void putDigit(int p, u32 v) {
    int g = p >> 6;
    if (supState[g >> 6]) materializeSuper(g >> 6);
    if (blkState[g]) materialize(g);
    dg[p] = v;
    updDigit(p);
}
static inline void recomputeBlock(int g) {
    if (supState[g >> 6]) materializeSuper(g >> 6);
    if (blkState[g]) materialize(g);
    u32 *q = dg + (g << 6);
    u64 f = 0, z = 0;
    for (int i = 0; i < 64; i++) {
        if (q[i] == MASK) f |= 1ULL << i;
        if (q[i] == 0) z |= 1ULL << i;
    }
    blkFull[g] = f; blkZero[g] = z;
    updBlockC(g);
}
// assign val (0 or MASK) to digits [l,r)
static inline void assignRange(int l, int r, u32 val) {
    if (l >= r) return;
    int c0 = l >> 12, c1 = (r - 1) >> 12;
    if (c0 == c1) {
        if (supState[c0]) materializeSuper(c0);
        int g0 = l >> 6, g1 = (r - 1) >> 6;
        if (g0 == g1) {
            if (blkState[g0]) materialize(g0);
            for (int i = l; i < r; i++) dg[i] = val;
            recomputeBlock(g0);
            return;
        }
        if (blkState[g0]) materialize(g0);
        for (int i = l; i < ((g0 + 1) << 6); i++) dg[i] = val;
        recomputeBlock(g0);
        for (int g = g0 + 1; g < g1; g++) { blkState[g] = (val == 0) ? 1 : 2; setBlockAll(g, val != 0); }
        if (blkState[g1]) materialize(g1);
        for (int i = g1 << 6; i < r; i++) dg[i] = val;
        recomputeBlock(g1);
        return;
    }
    // first partial c-entry
    if (supState[c0]) materializeSuper(c0);
    {
        int g0 = l >> 6, lim = (c0 + 1) << 6;
        if (blkState[g0]) materialize(g0);
        for (int i = l; i < (g0 + 1) << 6 && i < r; i++) dg[i] = val;
        recomputeBlock(g0);
        for (int g = g0 + 1; g < lim && g < NB; g++) { blkState[g] = (val == 0) ? 1 : 2; setBlockAll(g, val != 0); }
    }
    // full c-entries lazily
    for (int c = c0 + 1; c < c1; c++) {
        supState[c] = (val == 0) ? 1 : 2;
        u64 vm = validMaskBlocks(c);
        if (val == 0) { cFull[c] = 0ULL; cZero[c] = vm; }
        else { cFull[c] = vm; cZero[c] = 0ULL; }
    }
    // last partial c-entry
    if (supState[c1]) materializeSuper(c1);
    {
        int g1 = (r - 1) >> 6, lo = c1 << 6;
        for (int g = lo; g < g1; g++) { blkState[g] = (val == 0) ? 1 : 2; setBlockAll(g, val != 0); }
        if (blkState[g1]) materialize(g1);
        for (int i = g1 << 6; i < r; i++) dg[i] = val;
        recomputeBlock(g1);
    }
}

// first index >= p with dg[idx] != MASK
static inline int findNonFull(int p) {
    int c = p >> 12;
    if (supState[c]) {
        if (supState[c] == 1) return p;
        c++;
    } else {
        int g = p >> 6;
        u64 m = ~blkFull[g] & (~0ULL << (p & 63));
        if (m) return (g << 6) + __builtin_ctzll(m);
        int hi = (c + 1) << 6; if (hi > NB) hi = NB;
        for (int gg = g + 1; gg < hi; gg++)
            if (blkFull[gg] != ~0ULL) return (gg << 6) + __builtin_ctzll(~blkFull[gg]);
        c++;
    }
    for (; c < NC; c++) {
        if (supState[c]) {
            if (supState[c] == 1) return c << 12;
            continue;
        }
        u64 vm = validMaskBlocks(c);
        if ((~cFull[c] & vm) == 0ULL) continue;
        int lo = c << 6, hi = lo + 64; if (hi > NB) hi = NB;
        for (int g = lo; g < hi; g++)
            if (blkFull[g] != ~0ULL) return (g << 6) + __builtin_ctzll(~blkFull[g]);
    }
    return MAXD;
}
// first index >= p with dg[idx] != 0
static inline int findNonZero(int p) {
    int c = p >> 12;
    if (supState[c]) {
        if (supState[c] == 2) return p;
        c++;
    } else {
        int g = p >> 6;
        u64 m = ~blkZero[g] & (~0ULL << (p & 63));
        if (m) return (g << 6) + __builtin_ctzll(m);
        int hi = (c + 1) << 6; if (hi > NB) hi = NB;
        for (int gg = g + 1; gg < hi; gg++)
            if (blkZero[gg] != ~0ULL) return (gg << 6) + __builtin_ctzll(~blkZero[gg]);
        c++;
    }
    for (; c < NC; c++) {
        if (supState[c]) {
            if (supState[c] == 2) return c << 12;
            continue;
        }
        u64 vm = validMaskBlocks(c);
        if ((~cZero[c] & vm) == 0ULL) continue;
        int lo = c << 6, hi = lo + 64; if (hi > NB) hi = NB;
        for (int g = lo; g < hi; g++)
            if (blkZero[g] != ~0ULL) return (g << 6) + __builtin_ctzll(~blkZero[g]);
    }
    return MAXD;
}

static inline void setZeroRange(int l, int r) {
    if (l >= r) return;
    int g0 = l >> 6, g1 = (r - 1) >> 6;
    if (g0 == g1) { for (int i = l; i < r; i++) { dg[i] = 0; updDigit(i); } return; }
    for (int i = l; i < ((g0 + 1) << 6); i++) { dg[i] = 0; updDigit(i); }
    for (int g = g0 + 1; g < g1; g++) {
        memset(dg + (g << 6), 0, 64 * sizeof(u32));
        blkFull[g] = 0; blkZero[g] = ~0ULL; updBlockC(g);
    }
    for (int i = g1 << 6; i < r; i++) { dg[i] = 0; updDigit(i); }
}
static inline void setOnesRange(int l, int r) {
    if (l >= r) return;
    int g0 = l >> 6, g1 = (r - 1) >> 6;
    if (g0 == g1) { for (int i = l; i < r; i++) { dg[i] = MASK; updDigit(i); } return; }
    for (int i = l; i < ((g0 + 1) << 6); i++) { dg[i] = MASK; updDigit(i); }
    for (int g = g0 + 1; g < g1; g++) {
        u32 *p = dg + (g << 6);
        for (int t = 0; t < 64; t++) p[t] = MASK;
        blkFull[g] = ~0ULL; blkZero[g] = 0; updBlockC(g);
    }
    for (int i = g1 << 6; i < r; i++) { dg[i] = MASK; updDigit(i); }
}

static inline void addVal(int p, u32 v) {
    if (!v) return;
    u32 cur = getDigit(p);
    u64 y = (u64)cur + v;
    if (y <= MASK) { putDigit(p, (u32)y); return; }
    putDigit(p, (u32)(y - (1u << 30)));
    int t = findNonFull(p + 1);
    assignRange(p + 1, t, 0);
    putDigit(t, getDigit(t) + 1);
}
static inline void subVal(int p, u32 v) {
    if (!v) return;
    u32 cur = getDigit(p);
    if (cur >= v) { putDigit(p, cur - v); return; }
    putDigit(p, (u32)((u64)cur + (1u << 30) - v));
    int t = findNonZero(p + 1);
    assignRange(p + 1, t, MASK);
    putDigit(t, getDigit(t) - 1);
}


// SWAR 8-digit-at-a-time unsigned parser (bounded by end)
static inline u64 parseU(const char *&p, const char *end) {
    u64 v = 0;
    while (p + 8 <= end) {
        u64 x;
        __builtin_memcpy(&x, p, 8);
        u64 d = x - 0x3030303030303030ULL;
        if ((d + 0x0606060606060606ULL) & 0xF0F0F0F0F0F0F0F0ULL) break;
        u64 t = (d * 10 + (d >> 8)) & 0x00FF00FF00FF00FFULL;
        t = (t * 100 + (t >> 16)) & 0x0000FFFF0000FFFFULL;
        t = (t * 10000 + (t >> 32)) & 0xFFFFFFFFULL;
        v = v * 100000000ULL + t;
        p += 8;
    }
    while (p < end && *p >= '0' && *p <= '9') v = v * 10 + (*p++ - '0');
    return v;
}
static inline void skipToDigit(const char *&p, const char *end) {
    while (p < end && (*p < '0' || *p > '9')) p++;
}

int main() {
#ifdef TEST_IO
    static char inbuf[1 << 26];
    INSZ = fread(inbuf, 1, sizeof(inbuf), stdin);
    IN = inbuf;
    static char outbuf[1 << 24];
    OUT = outbuf; OUTLIM = sizeof(outbuf);
#else
    di = (struct DI *)DUCKINFO;
    IN = di->in; INSZ = di->insz;
    OUT = di->out; OUTLIM = di->outlim;
#endif
    for (int g = 0; g < NB; g++) { blkFull[g] = 0ULL; blkZero[g] = ~0ULL; }
    for (int c = 0; c < NC; c++) { cFull[c] = 0ULL; cZero[c] = ~0ULL; }

    const char *p = IN, *pend = IN + INSZ;
    long long n = (long long)parseU(p, pend);
    skipToDigit(p, pend); (void)parseU(p, pend);      // t1
    skipToDigit(p, pend); (void)parseU(p, pend);      // t2
    skipToDigit(p, pend); (void)parseU(p, pend);      // t3
    for (long long op = 0; op < n; op++) {
        skipToDigit(p, pend);
        long long t = (long long)parseU(p, pend);
        p++;                            // skip the single delimiter
        if (t == 1) {
            long long a;
            if (*p == '-') { p++; a = -(long long)parseU(p, pend); }
            else a = (long long)parseU(p, pend);
            p++;
            long long b = (long long)parseU(p, pend);
            p++;
            if (a == 0) continue;
            int q = (int)(b / 30);
            int r = (int)(b % 30);
            u64 av = (u64)(a > 0 ? a : -a);
            u64 sh = av << r;
            u32 s0 = (u32)(sh & MASK);
            u32 s1 = (u32)(sh >> 30);
            if (a > 0) { addVal(q, s0); addVal(q + 1, s1); }
            else { subVal(q, s0); subVal(q + 1, s1); }
        } else {
            long long k = (long long)parseU(p, pend);
            p++;
            if (OUTSZ + 2 <= OUTLIM) {
                OUT[OUTSZ++] = (char)('0' + ((getDigit((int)(k / 30)) >> (k % 30)) & 1u));
                OUT[OUTSZ++] = '\n';
            }
        }
    }
#ifdef TEST_IO
    fwrite(outbuf, 1, OUTSZ, stdout);
#else
    di->outsz = OUTSZ;
    register long rax __asm__("rax") = 60;
    register long rdi __asm__("rdi") = 0;
    __asm__ volatile("syscall" :: "a"(rax), "D"(rdi) : "rcx", "r11", "memory");
    __builtin_unreachable();
#endif
    return 0;
}

//ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp

CompilationN/AN/ACompile OKScore: N/A

Testcase #135.13 us268 KBAcceptedScore: 4

Testcase #238.25 us268 KBAcceptedScore: 4

Testcase #394.74 us268 KBAcceptedScore: 4

Testcase #4123.16 us272 KBAcceptedScore: 4

Testcase #5862.44 us272 KBAcceptedScore: 4

Testcase #6594.59 us276 KBAcceptedScore: 4

Testcase #72.015 ms308 KBAcceptedScore: 4

Testcase #81.274 ms276 KBAcceptedScore: 4

Testcase #98.317 ms404 KBAcceptedScore: 4

Testcase #1013.295 ms488 KBAcceptedScore: 4

Testcase #119.57 ms312 KBAcceptedScore: 4

Testcase #128.719 ms560 KBAcceptedScore: 4

Testcase #1315.916 ms584 KBAcceptedScore: 4

Testcase #1458.217 ms1 MB + 144 KBAcceptedScore: 4

Testcase #1553.261 ms1 MB + 596 KBAcceptedScore: 4

Testcase #16144.859 ms2 MB + 24 KBAcceptedScore: 4

Testcase #17118.425 ms632 KBAcceptedScore: 4

Testcase #18221.556 ms2 MB + 928 KBAcceptedScore: 4

Testcase #19284.651 ms3 MB + 356 KBAcceptedScore: 4

Testcase #2022.78 ms4 MB + 80 KBAcceptedScore: 4

Testcase #21229.318 ms4 MB + 232 KBAcceptedScore: 4

Testcase #22199.739 ms944 KBAcceptedScore: 4

Testcase #23543.299 ms4 MB + 400 KBAcceptedScore: 4

Testcase #24258.471 ms988 KBAcceptedScore: 4

Testcase #25514.074 ms4 MB + 676 KBAcceptedScore: 4


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