QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#744595#9631. Median ReplacementcpchenpiWA 1243ms7412kbC++204.4kb2024-11-13 22:34:162024-11-13 22:34:18

Judging History

你现在查看的是最新测评结果

  • [2024-11-13 22:34:18]
  • 评测
  • 测评结果:WA
  • 用时:1243ms
  • 内存:7412kb
  • [2024-11-13 22:34:16]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

constexpr int MOD = 1e9 + 7, N = 180;

// fact[k][n]: [x^n](1^k + 2^k + 3^k + ... x^k)
i64 comb[N + 5][N + 5], fact[N + 5][N + 5];

i64 modPow(i64 a, i64 p) {
    i64 ans = 1;
    while (p) {
        if (p & 1) ans = ans * a % MOD;
        a = a * a % MOD;
        p >>= 1;
    }
    return ans;
}

i64 inv(i64 x) { return modPow(x, MOD - 2); }

void preCalc() {
    comb[0][0] = 1;
    for (int i = 1; i <= N; i++) {
        comb[i][0] = 1;
        for (int j = 1; j <= i; j++) {
            comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
            comb[i][j] %= MOD;
        }
    }

    fact[0][1] = 1;
    for (int k = 1; k <= N; k++) {
        for (int i = 0; i <= k + 1; i++) {
            (fact[k][i] += comb[k + 1][i]) %= MOD;
        }
        for (int p = 0; p < k; p++) {
            for (int i = 0; i <= p + 1; i++) {
                fact[k][i] -= comb[k + 1][p] * fact[p][i] % MOD;
                fact[k][i] = (fact[k][i] + MOD) % MOD;
            }
        }
        for (int i = 0; i <= k + 1; i++) {
            (fact[k][i] *= inv(k + 1)) %= MOD;
        }
    }
}

using P = array<int, N + 1>;

i64 preSum(const P& t, int n) {
    i64 res = 0;
    for (int p = 0; p <= N; p++) {
        i64 tmp = 0;
        for (int i = 0; i <= p + 1; i++) {
            (tmp += t[p] * fact[p][i] % MOD * modPow(n, i) % MOD) %= MOD;
        }
        (res += tmp) %= MOD;
    }
    return res;
}

i64 rangeSum(const P& t, int l, int r) {
    return (preSum(t, r) + MOD - preSum(t, l - 1)) % MOD;
}

P polyMul(P x, P y) {
    P ans{};
    for (int i = 0; i <= N; i++) {
        for (int j = 0; i + j <= N; j++) {
            (ans[i + j] += (i64)x[i] * y[j] % MOD) %= MOD;
        }
    }
    return ans;
}

using T = array<array<P, 3>, 3>;

T matMul(T a, T b) {
    T res{};
    for (int i = 0; i < 3; i++) {
        for (int k = 0; k < 3; k++) {
            for (int j = 0; j < 3; j++) {
                P tmp = polyMul(a[i][k], b[k][j]);
                for (int p = 0; p <= N; p++) {
                    (res[i][j][p] += tmp[p]) %= MOD;
                }
            }
        }
    }
    return res;
}

P ep() {
    return {1};
}

T et() {
    T res{};
    res[0][0] = res[1][1] = res[2][2] = ep();
    return res;
}

constexpr int w = 256;
struct Segtree {    
    T tr[2 * w]{};

    Segtree() {
        fill(tr, tr + 2 * w, et());
    }

    void set(int p, T x) {
        int i = p + w;
        for (tr[i] = x, i >>= 1; i; i >>= 1) {
            tr[i] = matMul(tr[2 * i], tr[2 * i + 1]);
        }
    }

    T allProd() { return tr[1]; }
};

T from01(P p0, P p1) {
    T res{};
    res[0][1] = res[1][2] = res[2][2] = p0;
    res[2][0] = p1;
    return res;
}

void solve() {
    int n; cin >> n;
    i64 allMul = 1;
    vector<int> l(n), r(n);
    for (int i = 0; i < n; i++) cin >> l[i];
    for (int i = 0; i < n; i++) cin >> r[i];

    Segtree tr{};

    struct Event {
        int time;
        int pos;
        array<array<int, 2>, 2> change;

        bool operator<(const Event &o) {
            return time < o.time;
        }
    };

    vector<Event> events;
    events.push_back({0, 0, {}});

    for (int i = 0; i < n; i++) {
        int s = r[i] - l[i] + 1;
        (allMul *= s) %= MOD;
        P p0 = {0}, p1 = {s};
        tr.set(i, from01(p0, p1));
        
        events.push_back({l[i], i, {{{(s + l[i]) % MOD, MOD - 1}, {(MOD - l[i]) % MOD, 1}}}});
        events.push_back({r[i] + 1, i, {{{s}, {0}}}});
    }

    sort(events.begin(), events.end());

    i64 ans = 0;

    int m = events.size();
    for (int i = 0; i < m; i++) {
        auto [t, p, pr] = events[i];
        if (p != -1) tr.set(p, from01({pr[0][0], pr[0][1]}, {pr[1][0], pr[1][1]}));
        if (i + 1 < m && events[i].time != events[i + 1].time) {
            int tml = events[i].time, tmr = events[i + 1].time - 1;
            ans += (tmr - tml + 1) * allMul % MOD;
            ans -= rangeSum(tr.allProd()[2][0], tml, tmr);
            ans -= rangeSum(tr.allProd()[2][1], tml, tmr);
            ans -= rangeSum(tr.allProd()[2][2], tml, tmr);
            cout << tml << " " << tmr << ": " << ans << "\n";
            ((ans %= MOD) += MOD) %= MOD;
        }
    }
    cout << ans << "\n";
}

int main() {
    preCalc();
    int t; cin >> t; 
    while (t--) {
        solve();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1243ms
memory: 7412kb

input:

10
5
5 1 4 3 2
14 2 5 3 2
5
4 5 1 2 3
13 7 1 2 3
5
5 2 5 3 1
10 2 12 3 2
5
5 5 3 1 5
57 5 3 1 5
5
2 2 3 3 5
4 5 4 4 5
5
4 5 3 5 3
13 7 3 5 3
5
5 1 4 2 3
14 3 4 2 3
5
1 2 5 4 5
2 8 5 7 5
5
1 1 3 5 1
8 2 3 8 1
5
4 4 4 2 3
5 10 5 2 3

output:

0 0: 40
1 1: 80
2 2: 120
3 3: 160
4 4: 200
5 5: 200
6 14: 200
200
0 0: 30
1 1: 60
2 2: 90
3 3: 120
4 4: 120
5 7: 128
8 13: 128
128
0 0: 96
1 1: 192
2 2: 288
3 3: 384
4 4: 480
5 10: 590
11 12: 590
590
0 0: 53
1 1: 106
2 2: 159
3 3: 212
4 4: 265
5 5: 265
6 57: 265
265
0 1: 96
2 2: 144
3 4: 188
5 5: 18...

result:

wrong answer 1st lines differ - expected: '180', found: '0 0: 40'