QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#481723#8717. 骰子lilabTL 0ms22144kbC++206.9kb2024-07-17 13:34:102024-07-17 13:34:11

Judging History

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

  • [2024-07-17 13:34:11]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:22144kb
  • [2024-07-17 13:34:10]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long int
#define db double
#define tp ll
#define ptp pair<tp,tp>
#define pdb pair<db,db>
#define umap unordered_map
#define ed '\n'


using namespace std;

tp n, num, sum, flag, ans, tmp, ls, len, wz, pos, m, k, p, q;
tp sqrtn;
tp lt, rt, mid;
tp min1, min2, min3, max1, max2, max3;
string s;
tp h, w, t;

namespace anymod_poly {
    tp mod;

    tp ksm(tp a, tp b, tp p) {
        tp lsans = 1;
        while (b) {
            if (b & 1ll) {
                lsans = (lsans * a) % p;
            }
            a = (a * a) % p;
            b >>= 1;
        }
        return lsans;
    }

    tp inv(tp x, tp mod) { return ksm(x, mod - 2, mod); }

    const tp mod1 = 998244353, mod2 = 1004535809, mod3 = 469762049, G = 3;
    const ll mod_1_2 = static_cast<ll> (mod1) * mod2;
    const tp inv_1 = inv(mod1, mod2), inv_2 = inv(mod_1_2 % mod3, mod3);
    struct Int {
        ll A, B, C;
        explicit Int() { }
        explicit Int(ll __num) : A(__num), B(__num), C(__num) { }
        explicit Int(ll __A, ll __B, ll __C) : A(__A), B(__B), C(__C) { }
        static Int reduce(const Int& x) {
            return Int(x.A + (x.A >> 31 & mod1), x.B + (x.B >> 31 & mod2), x.C + (x.C >> 31 & mod3));
        }
        friend Int operator + (const Int& lhs, const Int& rhs) {
            return reduce(Int(lhs.A + rhs.A - mod1, lhs.B + rhs.B - mod2, lhs.C + rhs.C - mod3));
        }
        friend Int operator - (const Int& lhs, const Int& rhs) {
            return reduce(Int(lhs.A - rhs.A, lhs.B - rhs.B, lhs.C - rhs.C));
        }
        friend Int operator * (const Int& lhs, const Int& rhs) {
            return Int(static_cast<ll> (lhs.A) * rhs.A % mod1, static_cast<ll> (lhs.B) * rhs.B % mod2, static_cast<ll> (lhs.C) * rhs.C % mod3);
        }
        tp get() {
            ll x = static_cast<ll> (B - A + mod2) % mod2 * inv_1 % mod2 * mod1 + A;
            return (static_cast<ll> (C - x % mod3 + mod3) % mod3 * inv_2 % mod3 * (mod_1_2 % mod) % mod + x) % mod;
        }
    };

    tp lim, s;
    vector<tp>rev;
    vector<Int>Wn;
    void poly_init(tp n) {
        s = -1, lim = 1;
        while (lim < n) lim <<= 1, ++s;
        rev = vector<tp>(lim + 5);
        Wn = vector<Int>(lim + 5);
        for (register tp i = 1; i < lim; ++i) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
        const Int t(ksm(G, (mod1 - 1) / lim, mod1), ksm(G, (mod2 - 1) / lim, mod2), ksm(G, (mod3 - 1) / lim, mod3));
        Wn[0] = Int(1);
        for (auto it = Wn.begin(); it != Wn.begin() + lim; ++it) *(it + 1) = *it * t;
    }
    void ntt(Int* A, const tp op) {//传入的数组尺寸至少要比lim大
        for (register tp i = 1; i < lim; ++i) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
        for (register tp mid = 1; mid < lim; mid <<= 1) {
            const tp t = lim / mid >> 1;
            for (register tp i = 0; i < lim; i += mid << 1) {
                for (register tp j = 0; j < mid; ++j) {
                    const Int W = op ? Wn[t * j] : Wn[lim - t * j];
                    const Int X = A[i + j], Y = A[i + j + mid] * W;
                    A[i + j] = X + Y, A[i + j + mid] = X - Y;
                }
            }
        }
        if (!op) {
            const Int ilim(inv(lim, mod1), inv(lim, mod2), inv(lim, mod3));
            for (register Int* i = A; i != A + lim; ++i) *i = (*i) * ilim;
        }
    }

    void mul(Int* a, Int* b, Int* c) {
        for (tp i = 0; i < lim; ++i) c[i] = a[i] * b[i];
        ntt(c, 0);
        for (tp i = m + 1; i < lim; i++) {//去除大于m的阶
            c[i] = Int(0);
        }
        ntt(c, 1);
    }

}

using namespace anymod_poly;

Int b[520], bb[520];
Int a[1505][520];
Int pre[42][1505][520];
ptp qr[600005];
Int qk[42][42][42][520];


void init() {

}

void clear() {

}

void solve() {
    mod = 1e9 + 7;
    cin >> n >> m >> q;
    sqrtn = sqrt(n);
    poly_init(2 * m + 1);

    for (tp i = 0; i <= m; i++) {
        cin >> ls;
        b[i] = Int(ls % mod);
        bb[m - i] = b[i];
    }
    //将bb转化
    ntt(bb, 1);
    for (tp i = 1; i <= n; i++) {
        for (tp j = 0; j <= m; j++) {
            cin >> ls;
            a[i][j] = Int(ls % mod);
        }
    }

    for (tp i = 1; i <= n; i++) {
        tp id = (i - 1) / sqrtn + 1;
        for (tp j = 0; j <= m; j++) {
            qk[id][i - (id - 1) * sqrtn][i - (id - 1) * sqrtn][j] = a[i][j];
        }
        ntt(qk[id][i - (id - 1) * sqrtn][i - (id - 1) * sqrtn], 1);
    }
    //将a[i]转化
    for (tp i = 1; i <= n; i++) {
        ntt(a[i], 1);
        
    }

    for (tp i = 1; i <= q; i++) {
        cin >> qr[i].first >> qr[i].second;
    }


    for (tp i = 1; (i-1) * sqrtn <= n; i++) {
        pre[i][(i - 1) * sqrtn][0] = Int(1);
        ntt(pre[i][(i - 1) * sqrtn], 1);
    }
    for (tp i = 1; i <= n; i++) {
        tp id = (i - 1) / sqrtn + 1;
        for (tp j = 1; j <= id; j++) {
            mul(pre[j][i - 1], a[i], pre[j][i]);
        }
    }

    for (tp id = 1; id * sqrtn <= n; id++) {
        for (tp len = 2; len <= sqrtn; len++) {
            for (tp i = 1; i + len - 1 <= sqrtn; i++) {
                mul(qk[id][i][i], qk[id][i + 1][i + len - 1], qk[id][i][i + len - 1]);
            }
        }
    }
    for (tp id = 1; id * sqrtn <= n; id++) {
        for (tp len = 1; len <= sqrtn; len++) {
            for (tp i = 1; i + len - 1 <= sqrtn; i++) {
                mul(qk[id][i][i+len-1],bb,qk[id][i][i+len-1]);
            }
        }
    }

    for (tp id = 1; id * sqrtn <= n; id++) {
        for (tp len = 1; len <= sqrtn; len++) {
            for (tp i = 1; i + len - 1 <= sqrtn; i++) {
                ntt(qk[id][i][i + len - 1], 0);
            }
        }
    }

    for (tp i = 1; i <= n; i++) {
        tp id = (i - 1) / sqrtn + 1;
        for (tp j = 1; j <= id; j++) {
            ntt(pre[j][i], 0);
        }
    }
    

    for (tp i = 1; i <= q; i++) {
        lt = qr[i].first; rt = qr[i].second;
        tp lid = (lt - 1) / sqrtn + 1;
        tp rid = (rt - 1) / sqrtn + 1;
        if (lid == rid) {
            cout << qk[lid][lt - (lid - 1) * sqrtn][rt - (rid - 1) * sqrtn][m].get() << ed;
        }
        else {
            ans = 0;
            for (tp j = 0; j <= m; j++) {
                ans = (ans + qk[lid][lt - (lid - 1) * sqrtn][sqrtn][j].get() * pre[lid + 1][rt][m - j].get()) % mod;
            }
            cout << ans << ed;
        }
    }

}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int _t = 1;
    //cin >> _t;
    init();
    while (_t--) {
        solve();
    }
}
//样例
/*

3 3 3
4 3 2 1
0 1 0 1000000007
0 500000004 0 500000004
0 0 500000004 500000004
1 1
1 2
1 3


3 3 6
4 3 2 1
1000000007 0 1 0
1000000007 1 0 0
1000000007 0 1 0
1 1
1 2
1 3
2 2
2 3
3 3


*/


Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 22108kb

input:

3 3 3
4 3 2 1
0 1 0 1000000007
0 500000004 0 500000004
0 0 500000004 500000004
1 1
1 2
1 3

output:

3
1
0

result:

ok 3 number(s): "3 1 0"

Test #2:

score: 0
Accepted
time: 0ms
memory: 22144kb

input:

3 3 6
4 3 2 1
1000000007 0 1 0
1000000007 1 0 0
1000000007 0 1 0
1 1
1 2
1 3
2 2
2 3
3 3

output:

2
1
0
3
1
2

result:

ok 6 numbers

Test #3:

score: 0
Accepted
time: 0ms
memory: 13864kb

input:

1 1 1
604063100 57375033
742299910 257700098
1 1

output:

148903503

result:

ok 1 number(s): "148903503"

Test #4:

score: -100
Time Limit Exceeded

input:

1500 200 600000
253665324 876103781 804024983 929290295 908790466 176299158 528078340 696679927 416465140 509641654 705083449 361711737 250659645 735832780 35321360 383752049 203979021 178832532 785212637 514502839 169840231 65809146 504755349 516829442 382478309 901925498 142312128 782336477 741339...

output:

225533266
399052486
88496497
924016434
788274276
513479295
607446444
536822233
906901266
864827379
257479808
354648797
294773147
255419254
16061880
80445449
932530912
348852913
897966792
35482975
62912962
144223722
133795152
589147695
229693006
788114802
19486590
293071241
328806115
109798007
891863...

result: