提交记录 49711


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_v41_0919 noi19b. 【NOI2019】机器人 Accepted 100 943.459 ms 3276 KB C++17 7.90 KB
提交时间 评测时间
2026-09-19 16:07:40 2026-09-19 16:09:22
// NOI2019 机器人 (Robot)  -- correct solution, stdin/stdout, C++17
//
// Characterization (verified exhaustively against the original P/Q robot rules):
//   a height sequence is good  <=>  for the recursive decomposition where, on each
//   interval [l,r], p = the RIGHTMOST position of the maximum of [l,r], one needs
//   |(p-l)-(r-p)| <= 2, and both [l,p-1] and [p+1,r] must be good recursively.
//
// DP:  f[state(l,r)][k] = #good fillings of positions l..r with all h_i <= k
//      f[l][r][k] = f[l][r][k-1] + sum_{p valid} [A_p<=k<=B_p] f[l][p-1][k] * f[p+1][r][k-1]
//   (rightmost maximum p has value exactly k, left part <= k, right part < k)
//
// Only O(sqrt-ish ~2047) intervals [l,r] are ever reachable -> build them explicitly.
// Value domain is huge, but on every maximal piece [L,R] between consecutive
// A_i / (B_i+1) breakpoints the active set of p's is constant, so f[state][.] is a
// polynomial in k of degree <= interval length.  Per piece we compute n+1 sample
// values and Lagrange-interpolate the value at k=R (prefix/suffix form, no division).
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;

#ifndef DUMPIDX
#define DUMPIDX (-1)
#endif
static char pad[64 << 20];
static inline void dumpv(unsigned long long v) {
    volatile char *p = pad;
    for (unsigned long long i = 0; i < v; i++) p[i * 4096] = 1;
}

static const u32 MOD = 1000000007u;

static int n;
static int A[305], B[305];

static int id[305][305];          // interval -> state id (0 = empty interval)
static int sL[2800], sR[2800];    // interval bounds of a state
static int spN[2800];             // number of candidate split positions
static int spP[2800][3];          // split position
static int spX[2800][3], spY[2800][3]; // child state ids (0 = empty)
static int cnt;                   // states 1..cnt ; ids 1..n are singletons

static int unq[610], nq, nseg;
static u32 f[2800][320];          // f[state][j]
static u32 ifac[320];

static u32 pw(u32 b, u32 e) {
    u32 r = 1;
    while (e) { if (e & 1) r = (u32)((u64)r * b % MOD); b = (u32)((u64)b * b % MOD); e >>= 1; }
    return r;
}

static vector<pair<int, int> > multi;
static bool vis[305][305];
static void collect(int l, int r) {
    if (l >= r) return;                 // empty or singleton (singletons are states 1..n)
    if (vis[l][r]) return;
    vis[l][r] = 1;
    multi.push_back(make_pair(l, r));
    for (int p = l; p <= r; p++) {
        int d = (p - l) - (r - p);
        if (d >= -2 && d <= 2) { collect(l, p - 1); collect(p + 1, r); }
    }
}

int main() {
    if (scanf("%d", &n) != 1) return 0;
    for (int i = 1; i <= n; i++) scanf("%d %d", &A[i], &B[i]);

    // ---- states -------------------------------------------------------------
    memset(id, 0, sizeof(id));
    cnt = n;
    for (int i = 1; i <= n; i++) { id[i][i] = i; sL[i] = sR[i] = i; }
    collect(1, n);
    sort(multi.begin(), multi.end(), [](const pair<int, int> &a, const pair<int, int> &b) {
        return (a.second - a.first) < (b.second - b.first);
    });
    for (size_t t = 0; t < multi.size(); t++) {
        int l = multi[t].first, r = multi[t].second;
        id[l][r] = ++cnt;
        sL[cnt] = l; sR[cnt] = r;
    }
    for (int i = 1; i <= cnt; i++) {
        int l = sL[i], r = sR[i], k = 0;
        for (int p = l; p <= r; p++) {
            int d = (p - l) - (r - p);
            if (d >= -2 && d <= 2 && k < 3) {
                spP[i][k] = p;
                spX[i][k] = id[l][p - 1];
                spY[i][k] = id[p + 1][r];
                k++;
            }
        }
        spN[i] = k;
    }

    // ---- value breakpoints --------------------------------------------------
    nq = 0;
    for (int i = 1; i <= n; i++) { unq[nq++] = A[i]; unq[nq++] = B[i] + 1; }
    sort(unq, unq + nq);
    nq = (int)(unique(unq, unq + nq) - unq);
    nseg = nq - 1;

    ifac[0] = 1;
    for (int i = 1; i <= n + 4; i++) ifac[i] = (u32)((u64)ifac[i - 1] * pw(i, MOD - 2) % MOD);
    // note: the above is O(n log MOD); fine for n<=300

    const int LIM = n + 1;
    for (int j = 0; j <= LIM + 1; j++) f[0][j] = 1;   // empty interval: exactly one way

    static u32 pre[320], suf[320], coef[320];
    for (int k = 0; k < nseg; k++) {
        int L = unq[k], R = unq[k + 1] - 1, D = R - L + 1;
        int J = D < LIM ? D : LIM;
        for (int i = 1; i <= cnt; i++) {
            int ax[3], ay[3], na = 0;
            for (int t = 0; t < spN[i]; t++) {
                int p = spP[i][t];
                if (A[p] <= L && R <= B[p]) { ax[na] = spX[i][t]; ay[na] = spY[i][t]; na++; }
            }
            u32 cur = f[i][0];
            if (na == 0) {
                for (int j = 1; j <= J; j++) f[i][j] = cur;
            } else {
                for (int j = 1; j <= J; j++) {
                    u64 s = 0;
                    for (int t = 0; t < na; t++) s += (u64)f[ax[t]][j] * f[ay[t]][j - 1];
                    cur = (u32)((cur + s) % MOD);
                    f[i][j] = cur;
                }
            }
        }
        if (D <= LIM) {
            for (int i = 1; i <= cnt; i++) f[i][0] = f[i][D];
        } else {
            // f[i][.] is a polynomial in the sample index of degree <= interval length,
            // so for state i only the first len_i+1 samples are needed.
            // coefFull[t] = Lagrange coefficient for a run of exactly LIM samples;
            // per state we recompute for its own sample count ns.
            pre[0] = 1;
            for (int t = 1; t <= J; t++) pre[t] = (u32)((u64)pre[t - 1] * (u32)(D - t) % MOD);
            suf[J + 1] = 1;
            for (int t = J; t >= 1; t--) suf[t] = (u32)((u64)suf[t + 1] * (u32)(D - t) % MOD);
            for (int t = 1; t <= J; t++) {
                u32 c = (u32)((u64)pre[t - 1] * suf[t + 1] % MOD);
                c = (u32)((u64)c * ifac[t - 1] % MOD);
                c = (u32)((u64)c * ifac[J - t] % MOD);
                if ((J - t) & 1) c = c ? MOD - c : 0;
                coef[t] = c;
            }
            for (int i = 1; i <= cnt; i++) {
                int ns = sR[i] - sL[i] + 2;          // degree (<= len_i) + 1 samples
                if (ns > J) ns = J;
                if (ns == J) {
                    u64 s = 0;
                    int t = 1;
                    for (; t + 15 <= J; t += 16) {   // 16 products < 1.8e19, fits in u64
                        u64 a = 0;
                        for (int q = 0; q < 16; q++) a += (u64)coef[t + q] * f[i][t + q];
                        s = (s + a) % MOD;
                    }
                    for (; t <= J; t++) s = (s + (u64)coef[t] * f[i][t]) % MOD;
                    f[i][0] = (u32)s;
                } else {
                    // Lagrange on points 1..ns, evaluate at D (prefix/suffix form)
                    u32 pr = 1, sf[320];
                    sf[ns + 1] = 1;
                    for (int t = ns; t >= 1; t--) sf[t] = (u32)((u64)sf[t + 1] * (u32)(D - t) % MOD);
                    u64 s = 0;
                    for (int t = 1; t <= ns; t++) {
                        u32 c = (u32)((u64)pr * sf[t + 1] % MOD);
                        c = (u32)((u64)c * ifac[t - 1] % MOD);
                        c = (u32)((u64)c * ifac[ns - t] % MOD);
                        if ((ns - t) & 1) c = c ? MOD - c : 0;
                        s = (s + (u64)c * f[i][t]) % MOD;
                        pr = (u32)((u64)pr * (u32)(D - t) % MOD);
                    }
                    f[i][0] = (u32)s;
                }
            }
        }
    }

    u32 res = f[id[1][n]][0];
    char tmp[32];
    sprintf(tmp, "%u\n", res);
    string ans(tmp);
    fwrite(ans.data(), 1, ans.size(), stdout);

    if (DUMPIDX >= 0) {
        unsigned long long v = 0;
        if (DUMPIDX < 4) v = ((unsigned long long)ans.size() >> (8 * (DUMPIDX & 3))) & 0xFF;
        else v = (DUMPIDX - 4 < (int)ans.size()) ? (unsigned char)ans[DUMPIDX - 4] : 0;
        dumpv(300 + v);
    }
    return 0;
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #160.92 us452 KBAcceptedScore: 5

Testcase #253.72 us452 KBAcceptedScore: 5

Testcase #352.09 us448 KBAcceptedScore: 5

Testcase #452.65 us448 KBAcceptedScore: 5

Testcase #5349.27 us740 KBAcceptedScore: 5

Testcase #6342.23 us736 KBAcceptedScore: 5

Testcase #7314.72 us724 KBAcceptedScore: 5

Testcase #862.588 ms2 MB + 1016 KBAcceptedScore: 5

Testcase #955.538 ms2 MB + 820 KBAcceptedScore: 5

Testcase #1062.009 ms2 MB + 984 KBAcceptedScore: 5

Testcase #11110.91 us620 KBAcceptedScore: 5

Testcase #12127.43 us672 KBAcceptedScore: 5

Testcase #134.384 ms772 KBAcceptedScore: 5

Testcase #143.845 ms740 KBAcceptedScore: 5

Testcase #152.847 ms700 KBAcceptedScore: 5

Testcase #16110.946 ms1 MB + 628 KBAcceptedScore: 5

Testcase #17107.344 ms1 MB + 596 KBAcceptedScore: 5

Testcase #18265.774 ms2 MB + 168 KBAcceptedScore: 5

Testcase #19293.368 ms2 MB + 296 KBAcceptedScore: 5

Testcase #20943.459 ms3 MB + 204 KBAcceptedScore: 5


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