QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#104665#5820. 置换Alkaid30 63ms4244kbC++146.6kb2023-05-11 16:52:352023-05-11 16:52:38

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-11 16:52:38]
  • 评测
  • 测评结果:30
  • 用时:63ms
  • 内存:4244kb
  • [2023-05-11 16:52:35]
  • 提交

answer

#include <bits/stdc++.h>
#define N 12010
#define int long long

using namespace std;

const int mod = 998244353;

int t, n, m, k, a[N], dp[N], vis[N], cnt[N];
vector <int> arr;

namespace Math {
    
    const int M = 3000;

    int fac[N], ifac[N];

    inline void add(int &x, int y) {
        x = (x + y) % mod;
    }

    inline int power(int a, int b) {
        int res = 1;
        while(b) {
            if(b & 1)
                res = res * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return res;
    }

    inline void pre() {
        
        fac[0] = ifac[0] = 1;
        for(int i = 1; i <= M; i++)
            fac[i] = fac[i - 1] * i % mod;

        ifac[M] = power(fac[M], mod - 2);
        for(int i = M - 1; i; i--)
            ifac[i] = ifac[i + 1] * (i + 1) % mod;
    
    }

    inline int C(int n, int m) {
        if(n < 0 || m < 0 || n - m < 0)
            return 0;
        return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
    }
}

using namespace Math;

namespace Polynomial {
    typedef vector <int> poly;
    int rev[N];
    const int G = 3, invG = power(G, mod - 2), inv2 = power(2, mod - 2);

    inline void reset(poly A) {
        for(int i = 0; i < A.size(); i++)
            A[i] = 0;
    }

    poly Mul_Con(poly A, int C) {
        for(int i = 0; i < A.size(); i++)
            A[i] *= C;
        return A;
    }

    inline int initrev(const int n) {
        int len = 1;
        while(len <= n)
            len <<= 1;
        for(int i = 0; i < len; i++) {
            rev[i] = rev[i >> 1] >> 1;
            if(i & 1)
                rev[i] |= len >> 1;
        }
        return len;
    }

    inline poly Diff(poly arr) {
        const int n = arr.size();
        for(int i = 1; i < n; i++) 
            arr[i - 1] = arr[i] * i % mod;
        arr.resize(n - 1);
        return arr;
    }
    
    inline poly Inte(poly arr) {
        const int n = arr.size();
        arr.resize(n + 1);
        for(int i = n; i; i--) {
            arr[i] = arr[i - 1] * power(i, mod - 2) % mod;
        }
        arr[0] = 0;
        return arr;
    }
    
    inline void NTT(poly &arr, const int len, const int op) {
        arr.resize(len);
        for(int i = 0; i < len; i++) {
            if(i < rev[i])
                swap(arr[i], arr[rev[i]]);
        }
        for(int i = 2; i <= len; i <<= 1) {
            int wn = power(op ? G : invG, (mod - 1) / i);
            for(int j = 0; j < len; j += i) {
                int w = 1;
                for(int k = j; k < j + i / 2; k++, w = 1ll * w * wn % mod) {
                    int x = arr[k], y = 1ll * w * arr[k + i / 2] % mod;
                    arr[k] = (x + y) % mod;
                    arr[k + i / 2] = (x - y + mod) % mod;
                } 
            }
        }
        if(op)
            return;
        int invn = power(len, mod - 2);
        for(int i = 0; i < len; i++)
            arr[i] = arr[i] * invn % mod;
    }

    inline poly Mul(poly A, poly B) {

        int n = A.size() + B.size() - 1, len = initrev(n);
        poly C;
        C.resize(len);
        NTT(A, len, 1);
        NTT(B, len, 1);
        for(int i = 0; i < len; i++) {
            C[i] = A[i] * B[i] % mod;
        }
        NTT(C, len, 0);
        C.resize(n);
        return C;
    }

    inline poly Inv(poly arr, const int n) {
        if(n == 1) {
            return poly(1, power(arr[0], mod - 2));
        }
        poly A(arr.begin(), arr.begin() + n);
        poly B = Inv(arr, (n + 1) >> 1);
        int len = initrev(n << 1);
        NTT(A, len, 1);
        NTT(B, len, 1);

        for(int i = 0; i < len; i++) {

            A[i] = 1ll * B[i] * (2 - 1ll * A[i] * B[i] % mod + mod) % mod;
        }
        NTT(A, len, 0);
        A.resize(n);
        return A;   
    }

    //!  arr[0] = 1;
    poly Sqrt(poly arr, int n) {
        if(n == 1)
            return poly(1, 1);
        poly A(arr.begin(), arr.begin() + n);
        poly B = Sqrt(arr, (n + 1) >> 1);
        B.resize(n);
        poly C = Inv(B, n);
        const int len = initrev(n << 1);
        NTT(A, len, 1);
        NTT(C, len, 1);
        for(int i = 0; i < len; i++) 
            A[i] = A[i] * C[i] % mod;
        NTT(A, len, 0);
        for(int i = 0; i < n; i++) 
            A[i] = (A[i] + B[i]) * inv2 % mod;
        A.resize(n);
        return A;
    }

    inline poly Ln(poly arr, int n) {
        poly B = Inte(Mul(Diff(arr), Inv(arr, n)));
        B.resize(n);
        return B;
    }

    inline poly Exp(poly arr, int n) {
        if(n == 1)
            return poly(1, 1);
        poly A = Exp(arr, (n + 1) >> 1);
        A.resize(n);
        poly B = Ln(A, n);
        for(int i = 0; i < n; i++)
            B[i] = (arr[i] - B[i] + mod) % mod;
        const int len = initrev(n << 1);
        NTT(A, len, 1);
        NTT(B, len, 1);
        for(int i = 0; i < len; i++) {
            A[i] = A[i] * (1 + B[i]) % mod;
        }
        NTT(A, len, 0);
        A.resize(n);
        return A;
    }
}

using namespace Polynomial;

inline int solve(int n, int m) {

    arr.clear();
    memset(dp, 0, sizeof dp);

    for(int i = 1; i <= n; i++)
        if(__gcd(m * i, k) == i)
            arr.push_back(i);

    poly A;
    A.clear();
    A.resize(n + 1);
    for(int u : arr) {
        A[u] = power(u, mod - 2);
    }

    A = Mul_Con(A, m);
    A = Exp(A, n + 1);


    dp[0] = 1;
    for(int i = 1; i <= n; i++){
        for(int u : arr) {
            if(u > i)
                break;
            add(dp[i], dp[i - u] * C(i - 1, u - 1) % mod * fac[u - 1] % mod * power(m, u - 1) % mod);
        }
    }   

    if(n == 1)
        return dp[n];

   // cout << m << ' ' << A[n] * fac[n] % mod << ' ' << dp[n] << endl;
    return A[n] * fac[n] % mod;
}

signed main() {

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    pre();

    cin >> t;
    
    while(t--) {
        
        memset(vis, 0, sizeof vis);
        memset(cnt, 0, sizeof cnt);

        cin >> n >> k;

        for(int i = 1; i <= n; i++)
            cin >> a[i];
        
        for(int i = 1; i <= n; i++) {
            if(vis[i])
                continue;
            int u = i, sz = 0;

            while(!vis[u]){
                vis[u] = 1;
                ++sz;
                u = a[u];
            }
        
            cnt[sz]++;
        }

        int ans = 1;

        for(int i = 1; i <= n; i++)
            if(cnt[i])
                ans = ans * solve(cnt[i], i) % mod;

        cout << ans << endl;
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 10
Accepted
time: 2ms
memory: 3792kb

input:

10
6 5
1 2 6 3 4 5
5 8
1 2 3 4 5
7 5
1 2 3 4 5 6 7
4 4
1 2 3 4
7 7
1 2 3 4 5 6 7
4 4
1 2 3 4
5 4
1 2 4 3 5
8 8
1 2 3 4 5 6 7 8
4 5
1 3 2 4
6 6
1 2 3 4 5 6

output:

1
56
505
16
721
16
0
11264
1
396

result:

ok 10 lines

Test #2:

score: 10
Accepted
time: 2ms
memory: 3792kb

input:

10
4 6
3 1 2 4
5 8
2 1 3 4 5
8 4
1 2 3 4 5 6 7 8
6 5
4 1 2 3 5 6
5 5
1 2 3 4 5
5 5
1 2 3 4 5
6 7
1 2 3 4 5 6
6 4
1 2 3 4 5 6
6 7
6 1 2 3 4 5
7 6
1 2 3 4 5 6 7

output:

0
0
6224
1
25
25
1
256
1
2052

result:

ok 10 lines

Test #3:

score: 10
Accepted
time: 2ms
memory: 3756kb

input:

10
6 602552
1 2 3 4 5 6
4 775694
1 2 4 3
6 668467
1 4 2 3 5 6
6 558385
1 2 6 3 4 5
7 832183
4 1 2 3 5 6 7
6 631375
1 2 3 4 5 6
8 519340
1 2 3 5 4 6 7 8
4 636124
1 2 3 4
4 759099
3 1 2 4
7 977752
1 2 3 4 5 6 7

output:

256
0
1
1
1
145
0
16
0
1072

result:

ok 10 lines

Test #4:

score: 0
Wrong Answer
time: 4ms
memory: 3844kb

input:

10
43 725761
1 2 3 4 5 6 7 8 10 9 11 12 13 15 14 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
37 542860
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 27 26 28 29 30 31 32 33 34 36 35 37
27 793967
2 1 4 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

output:

4
0
8
656150888
0
81372935
449319403
609543892
0
790474148

result:

wrong answer 1st lines differ - expected: '1', found: '4'

Test #5:

score: 0
Wrong Answer
time: 1ms
memory: 3828kb

input:

10
40 535121
3 1 2 4 5 6 7 8 9 11 10 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
43 660193
1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 15 19 17 18 20 26 21 22 23 24 25 27 28 29 30 34 31 32 33 35 36 37 38 39 40 41 42 43
38 596459
1 2 4 3 5 6 7 8 9 10 11 12 13 15 14 ...

output:

1
544069454
532271434
625999215
0
0
0
0
0
585634854

result:

wrong answer 3rd lines differ - expected: '632190035', found: '532271434'

Test #6:

score: 0
Wrong Answer
time: 0ms
memory: 3900kb

input:

10
33 892596
1 2 6 3 4 5 9 7 8 10 11 12 14 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 32 30 31 33
39 875634
1 2 10 3 4 5 6 7 8 9 11 12 13 14 16 15 17 18 20 19 21 22 23 24 26 25 27 28 29 30 31 32 33 35 34 36 37 38 39
27 856117
1 2 3 4 5 10 6 7 8 9 11 12 13 14 15 16 17 18 20 19 21 24 22 23 25 26 ...

output:

0
0
1
0
860677875
281504655
321535122
338992584
1
375191608

result:

wrong answer 6th lines differ - expected: '959811756', found: '281504655'

Test #7:

score: 0
Wrong Answer
time: 63ms
memory: 4240kb

input:

10
2899 540778
3 1 2 4 5 6 9 7 8 10 11 12 13 14 15 16 17 18 19 20 21 22 24 23 27 25 26 28 29 30 31 32 33 34 35 37 36 38 39 40 41 42 44 43 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 70 68 69 71 72 73 74 75 76 77 78 80 79 81 82 83 89 84 85 86 87 88 90 91 92 93 94 95 96 97 98 ...

output:

0
190876279
0
0
878660333
147117956
0
192733879
0
90139612

result:

wrong answer 2nd lines differ - expected: '786737927', found: '190876279'

Test #8:

score: 0
Wrong Answer
time: 56ms
memory: 4176kb

input:

10
2310 568163
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 26 24 25 27 28 30 29 31 32 33 34 35 36 37 38 39 40 41 46 42 43 44 45 47 48 49 50 51 52 57 53 54 55 56 58 59 61 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 ...

output:

492181601
0
835745349
0
319617113
655432468
0
0
0
197475466

result:

wrong answer 1st lines differ - expected: '1', found: '492181601'

Test #9:

score: 0
Wrong Answer
time: 50ms
memory: 4176kb

input:

10
1564 511376
1 2 3 4 5 6 8 7 9 10 11 12 13 14 15 16 20 17 18 19 21 22 23 24 25 26 28 27 29 30 31 35 32 33 34 36 41 37 38 39 40 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 76 74 75 77 78 82 79 80 81 83 84 85 86 87 88 89 90 91 92 93 94 97 95 96 98 ...

output:

0
503231157
0
0
713246234
0
0
0
0
704829532

result:

wrong answer 2nd lines differ - expected: '207595358', found: '503231157'

Test #10:

score: 0
Wrong Answer
time: 55ms
memory: 4244kb

input:

10
1749 969801
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 34 31 32 33 36 35 37 38 39 40 41 42 43 44 45 46 48 47 49 50 51 54 52 53 55 56 57 58 60 59 61 62 63 64 65 66 67 68 69 70 71 72 73 75 74 76 77 78 79 80 81 82 83 84 85 86 89 87 88 90 91 92 93 94 95 96 97 99 ...

output:

0
0
363693360
261425716
45701974
0
0
0
0
49171103

result:

wrong answer 3rd lines differ - expected: '1', found: '363693360'