QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#88946#5820. 置换phtniit0 0ms0kbC++144.4kb2023-03-18 00:31:022023-03-18 00:31:05

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-18 00:31:05]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2023-03-18 00:31:02]
  • 提交

answer

#include <bits/stdc++.h>

namespace atcoder {

constexpr int P = 998244353;
using i64 = long long;

// assume -P <= x < 2P
int norm(int x) {
  if (x < 0) {
    x += P;
  }
  if (x >= P) {
    x -= P;
  }
  return x;
}
template<class T>
T fpower(T a, i64 b) {
  T res = 1;
  for (; b; b /= 2, a *= a) {
    if (b % 2) {
      res *= a;
    }
  }
  return res;
}
struct Z {
  int x;
  Z(int x = 0) : x(norm(x)) {}
  Z(i64 x) : x(norm(x%P)) {}
  int val() const {
    return x;
  }
  Z operator-() const {
    return Z(x == 0 ? 0 : P-x);
    //return Z(norm(P - x));
  }
  Z inv() const {
    assert(x != 0);
    return fpower(*this, P - 2);
  }
  Z &operator*=(const Z &rhs) {
    x = i64(x) * rhs.x % P;
    return *this;
  }
  Z &operator+=(const Z &rhs) {
    x += rhs.x;
    if (x >= P) x -= P;
    //x = norm(x + rhs.x);
    return *this;
  }
  Z &operator-=(const Z &rhs) {
    x -= rhs.x;
    if (x < 0) x += P;
    //x = norm(x - rhs.x);
    return *this;
  }
  Z &operator/=(const Z &rhs) {
    return *this *= rhs.inv();
  }
  friend Z operator*(const Z &lhs, const Z &rhs) {
    Z res = lhs;
    res *= rhs;
    return res;
  }
  friend Z operator+(const Z &lhs, const Z &rhs) {
    Z res = lhs;
    res += rhs;
    return res;
  }
  friend Z operator-(const Z &lhs, const Z &rhs) {
    Z res = lhs;
    res -= rhs;
    return res;
  }
  friend Z operator/(const Z &lhs, const Z &rhs) {
    Z res = lhs;
    res /= rhs;
    return res;
  }
  friend std::istream &operator>>(std::istream &is, Z &a) {
    i64 v;
    is >> v;
    a = Z(v);
    return is;
  }
  friend std::ostream &operator<<(std::ostream &os, const Z &a) {
    return os << a.val();
  }
};

namespace simp {
  std::vector<Z> fac, ifac, invn;
  void check(int x) {
    if (fac.empty()) {
      fac={Z(1), Z(1)};
      ifac={Z(1), Z(1)};
      invn={Z(0), Z(1)};
    }
    while (fac.size()<=x) {
      int n = fac.size(), m = fac.size() * 2;
      fac.resize(m);
      ifac.resize(m);
      invn.resize(m);
      for (int i=n;i<m;i++) {
        fac[i]=fac[i-1]*Z(i);
        invn[i]=Z(P-P/i)*invn[P%i];
        ifac[i]=ifac[i-1]*invn[i];
      }
    }
  }
  Z gfac(int x) {
    check(x); return fac[x];
  }
  Z ginv(int x) {
    check(x); return invn[x];
  }
  Z gifac(int x) {
    check(x); return ifac[x];
  }
  Z binom(int n,int m) {
    if (m < 0 || m > n) return Z(0);
    return gfac(n)*gifac(m)*gifac(n - m);
  }
}

}

inline atcoder::Z C(int n, int m) {
  return atcoder::simp::binom(n, m);
}
inline atcoder::Z F(int n) {
  return atcoder::simp::gfac(n);
}
inline atcoder::Z iF(int n) {
  return atcoder::simp::gifac(n);
}

inline atcoder::Z fpow(long long a, long long b) {
  return atcoder::fpower(atcoder::Z{a}, b);
}

using namespace std;
using i64 = long long;

const int maxn = 1000050;

vector<int> D[maxn];
atcoder::Z p[3030][3030];

void once() {
  int n, k;
  scanf("%d %d", &n, &k);
  static int a[3030], cnt[3030];
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    cnt[i] = 0;
  }
  map<int, int> M;
  for (int i = 1; i <= n; ++i) if (!cnt[i]) {
    int num = 0;
    for (int j = i; cnt[j] == 0; j = a[j]) {
      num++;
      cnt[j] = 1;
    }
    M[num]++;
  }

  atcoder::Z ans = 1;
  for (auto e: M) {
    static int T = 0;
    std::function<atcoder::Z(int)> dfs = [&](int c) {
      if (c == 0) {
        return atcoder::Z{1};
      }
      static atcoder::Z dp[3030];
      static int vis[3030];
      if (vis[c] == T) {
        return dp[c];
      }
      vis[c] = T;

      atcoder::Z res = 0;
      for (auto d: D[k]) {
        if (d > c) {
          break;
        }
        if (__gcd(e.first, k/d) != 1) {
          continue;
        }
        res += C(c-1, d-1) * F(d-1) * p[e.first][d-1] * dfs(c - d);
      }
      return dp[c] = res;
    };
    ++T;
    auto res = dfs(e.second);
    if (res.x == 0) {
      puts("0");
      return;
    }
    ans *= res;
  }
  printf("%d\n", ans.x);
}

int main() {
  const int lim = 1000000;
  for (int i = 1; i <= lim; ++i) {
    for (int j = i; j <= lim; j += i) {
      D[j].emplace_back(i);
    }
  }
  for (int i = 1; i <= 3000; ++i) {
    p[i][0] = 1;
    for (int j = 1; j <= 3000/i; ++j) {
      p[i][j] = p[i][j-1] * i;
    }
  }

  int tes;
  scanf("%d", &tes);
  while (tes--) {
    once();
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

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:


result:


Test #2:

score: 0
Time Limit Exceeded

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:


result:


Test #3:

score: 0
Time Limit Exceeded

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:


result:


Test #4:

score: 0
Time Limit Exceeded

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:


result:


Test #5:

score: 0
Time Limit Exceeded

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:


result:


Test #6:

score: 0
Time Limit Exceeded

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:


result:


Test #7:

score: 0
Time Limit Exceeded

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:


result:


Test #8:

score: 0
Time Limit Exceeded

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:


result:


Test #9:

score: 0
Time Limit Exceeded

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:


result:


Test #10:

score: 0
Time Limit Exceeded

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:


result: