結果

問題 No.2349 Power!! (Hard)
ユーザー ytqm3ytqm3
提出日時 2023-06-10 21:33:24
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 863 ms / 7,000 ms
コード長 2,705 bytes
コンパイル時間 5,368 ms
コンパイル使用メモリ 273,280 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-06-11 00:17:08
合計ジャッジ時間 13,307 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
5,248 KB
testcase_01 AC 584 ms
5,376 KB
testcase_02 AC 594 ms
5,376 KB
testcase_03 AC 583 ms
5,376 KB
testcase_04 AC 204 ms
5,376 KB
testcase_05 AC 460 ms
5,376 KB
testcase_06 AC 830 ms
5,376 KB
testcase_07 AC 863 ms
5,376 KB
testcase_08 AC 839 ms
5,376 KB
testcase_09 AC 826 ms
5,376 KB
testcase_10 AC 847 ms
5,376 KB
testcase_11 AC 844 ms
5,376 KB
testcase_12 AC 842 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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

template <class mint> vector<mint> MiddleProd(vector<mint> f, vector<mint> g) {
  int N = f.size(), M = g.size();
  assert(N >= M);
  reverse(g.begin(), g.end());
  vector<mint> h = atcoder::convolution(f, g);
  vector<mint> res(N - M + 1);
  for (int i = M - 1; i < N; ++i) {
    res[i - (M - 1)] = h[i];
  }
  return res;
}

template <class mint>
vector<mint> MultiEvalGeomSeq(vector<mint> f, mint r, int M) {
  if (f.size() == 0) {
    vector<mint> res(M);
    return res;
  }
  int N = f.size();
  auto calc = [&](mint q, int K) {
    // q^Tr(i) を計算
    vector<mint> res(K, 1);
    mint nw = 1;
    for (int i = 1; i < K; ++i) {
      nw *= q;
      res[i] = res[i - 1] * nw;
    }
    return res;
  };
  vector<mint> A = calc(r, N + M - 1), B = calc(mint(1) / r, max(N, M));
  for (int i = 0; i < N; ++i) {
    f[i] *= B[i];
  }
  auto g = MiddleProd(A, f);
  for (int i = 0; i < M; ++i) {
    g[i] *= B[i];
  }
  return g;
}

template <class mint> void AllInv(vector<mint> &f) {
  int n = f.size();
  vector<mint> res(n + 1, 1);
  for (int i = 0; i < n; ++i) {
    res[i + 1] = res[i] * f[i];
  }
  mint t = mint(1) / res[n];
  res.pop_back();
  for (int i = n - 1; i >= 0; --i) {
    res[i] *= t;
    t *= f[i];
  }
  f = move(res);
}

void solve() {
  constexpr i64 P = 998244353, D = (1 << 13) * 119, E = (P - 1) / D;
  using mint = atcoder::static_modint<P>;
  i64 A, N;
  cin >> A >> N;
  i64 L = N / D, R = N % D;
  mint nw, nw2, cff;
  auto h = [&](int n) {
    i64 m = n / E;
    vector<mint> g(m);
    mint ee = mint(A).pow(E * E);
    nw = 1, cff = 1;
    for (i64 i = 0; i < m; ++i) {
      g[i] = nw;
      nw *= ee * cff;
      cff *= ee * ee;
    }
    auto W = MultiEvalGeomSeq(g, mint(A).pow(2 * E), E);
    vector<mint> res(E);
    nw = 1, cff = 1;
    for (i64 i = 0; i < E; ++i) {
      res[i] += nw * W[i];
      nw *= A * cff;
      cff *= A * A;
    }
    nw = mint(A).pow(m * m * E * E), cff = mint(A).pow(2 * m * E);
    for (i64 i = m * E; i < n; ++i) {
      res[i % E] += nw;
      nw *= A * cff;
      cff *= A * A;
    }
    return res;
  };
  vector<mint> X = h(D), Y = h(R);
  mint ans = 0, d2 = mint(A).pow(2 * D), ld2 = mint(A).pow(2 * L * D);
  nw = 1;
  vector<mint> Inv(E);
  for (i64 t = 0; t < E; ++t) {
    Inv[t] = -nw + 1;
    if (Inv[t] == 0) {
      Inv[t] = 1;
    }
    nw *= d2;
  }
  AllInv(Inv);
  nw = 1, nw2 = 1;
  for (i64 t = 0; t < E; ++t) {
    ans += (nw2 == mint(1) ? L : (-nw + 1) * Inv[t]) * X[t] + nw * Y[t];
    nw *= ld2;
    nw2 *= d2;
  }
  cout << ans.val() << endl;
}

int main() {
  int T;
  cin >> T;
  while (T--) {
    solve();
  }
}
0