QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#214070#6548. Coursesucup-team087#WA 239ms58520kbC++1412.0kb2023-10-14 17:05:432023-10-14 17:05:43

Judging History

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

  • [2023-10-14 17:05:43]
  • 评测
  • 测评结果:WA
  • 用时:239ms
  • 内存:58520kb
  • [2023-10-14 17:05:43]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
constexpr unsigned MO = 998244353U;
constexpr unsigned MO2 = 2U * MO;
constexpr int FFT_MAX = 23;
using Mint = ModInt<MO>;
constexpr Mint FFT_ROOTS[FFT_MAX + 1] = {1U, 998244352U, 911660635U, 372528824U, 929031873U, 452798380U, 922799308U, 781712469U, 476477967U, 166035806U, 258648936U, 584193783U, 63912897U, 350007156U, 666702199U, 968855178U, 629671588U, 24514907U, 996173970U, 363395222U, 565042129U, 733596141U, 267099868U, 15311432U};
constexpr Mint INV_FFT_ROOTS[FFT_MAX + 1] = {1U, 998244352U, 86583718U, 509520358U, 337190230U, 87557064U, 609441965U, 135236158U, 304459705U, 685443576U, 381598368U, 335559352U, 129292727U, 358024708U, 814576206U, 708402881U, 283043518U, 3707709U, 121392023U, 704923114U, 950391366U, 428961804U, 382752275U, 469870224U};
constexpr Mint FFT_RATIOS[FFT_MAX] = {911660635U, 509520358U, 369330050U, 332049552U, 983190778U, 123842337U, 238493703U, 975955924U, 603855026U, 856644456U, 131300601U, 842657263U, 730768835U, 942482514U, 806263778U, 151565301U, 510815449U, 503497456U, 743006876U, 741047443U, 56250497U, 867605899U};
constexpr Mint INV_FFT_RATIOS[FFT_MAX] = {86583718U, 372528824U, 373294451U, 645684063U, 112220581U, 692852209U, 155456985U, 797128860U, 90816748U, 860285882U, 927414960U, 354738543U, 109331171U, 293255632U, 535113200U, 308540755U, 121186627U, 608385704U, 438932459U, 359477183U, 824071951U, 103369235U};

// as[rev(i)] <- \sum_j \zeta^(ij) as[j]
void fft(Mint *as, int n) {
  assert(!(n & (n - 1))); assert(1 <= n); assert(n <= 1 << FFT_MAX);
  int m = n;
  if (m >>= 1) {
    for (int i = 0; i < m; ++i) {
      const unsigned x = as[i + m].x;  // < MO
      as[i + m].x = as[i].x + MO - x;  // < 2 MO
      as[i].x += x;  // < 2 MO
    }
  }
  if (m >>= 1) {
    Mint prod = 1U;
    for (int h = 0, i0 = 0; i0 < n; i0 += (m << 1)) {
      for (int i = i0; i < i0 + m; ++i) {
        const unsigned x = (prod * as[i + m]).x;  // < MO
        as[i + m].x = as[i].x + MO - x;  // < 3 MO
        as[i].x += x;  // < 3 MO
      }
      prod *= FFT_RATIOS[__builtin_ctz(++h)];
    }
  }
  for (; m; ) {
    if (m >>= 1) {
      Mint prod = 1U;
      for (int h = 0, i0 = 0; i0 < n; i0 += (m << 1)) {
        for (int i = i0; i < i0 + m; ++i) {
          const unsigned x = (prod * as[i + m]).x;  // < MO
          as[i + m].x = as[i].x + MO - x;  // < 4 MO
          as[i].x += x;  // < 4 MO
        }
        prod *= FFT_RATIOS[__builtin_ctz(++h)];
      }
    }
    if (m >>= 1) {
      Mint prod = 1U;
      for (int h = 0, i0 = 0; i0 < n; i0 += (m << 1)) {
        for (int i = i0; i < i0 + m; ++i) {
          const unsigned x = (prod * as[i + m]).x;  // < MO
          as[i].x = (as[i].x >= MO2) ? (as[i].x - MO2) : as[i].x;  // < 2 MO
          as[i + m].x = as[i].x + MO - x;  // < 3 MO
          as[i].x += x;  // < 3 MO
        }
        prod *= FFT_RATIOS[__builtin_ctz(++h)];
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    as[i].x = (as[i].x >= MO2) ? (as[i].x - MO2) : as[i].x;  // < 2 MO
    as[i].x = (as[i].x >= MO) ? (as[i].x - MO) : as[i].x;  // < MO
  }
}

// as[i] <- (1/n) \sum_j \zeta^(-ij) as[rev(j)]
void invFft(Mint *as, int n) {
  assert(!(n & (n - 1))); assert(1 <= n); assert(n <= 1 << FFT_MAX);
  int m = 1;
  if (m < n >> 1) {
    Mint prod = 1U;
    for (int h = 0, i0 = 0; i0 < n; i0 += (m << 1)) {
      for (int i = i0; i < i0 + m; ++i) {
        const unsigned long long y = as[i].x + MO - as[i + m].x;  // < 2 MO
        as[i].x += as[i + m].x;  // < 2 MO
        as[i + m].x = (prod.x * y) % MO;  // < MO
      }
      prod *= INV_FFT_RATIOS[__builtin_ctz(++h)];
    }
    m <<= 1;
  }
  for (; m < n >> 1; m <<= 1) {
    Mint prod = 1U;
    for (int h = 0, i0 = 0; i0 < n; i0 += (m << 1)) {
      for (int i = i0; i < i0 + (m >> 1); ++i) {
        const unsigned long long y = as[i].x + MO2 - as[i + m].x;  // < 4 MO
        as[i].x += as[i + m].x;  // < 4 MO
        as[i].x = (as[i].x >= MO2) ? (as[i].x - MO2) : as[i].x;  // < 2 MO
        as[i + m].x = (prod.x * y) % MO;  // < MO
      }
      for (int i = i0 + (m >> 1); i < i0 + m; ++i) {
        const unsigned long long y = as[i].x + MO - as[i + m].x;  // < 2 MO
        as[i].x += as[i + m].x;  // < 2 MO
        as[i + m].x = (prod.x * y) % MO;  // < MO
      }
      prod *= INV_FFT_RATIOS[__builtin_ctz(++h)];
    }
  }
  if (m < n) {
    for (int i = 0; i < m; ++i) {
      const unsigned y = as[i].x + MO2 - as[i + m].x;  // < 4 MO
      as[i].x += as[i + m].x;  // < 4 MO
      as[i + m].x = y;  // < 4 MO
    }
  }
  const Mint invN = Mint(n).inv();
  for (int i = 0; i < n; ++i) {
    as[i] *= invN;
  }
}

void fft(vector<Mint> &as) {
  fft(as.data(), as.size());
}
void invFft(vector<Mint> &as) {
  invFft(as.data(), as.size());
}

vector<Mint> convolve(vector<Mint> as, vector<Mint> bs) {
  if (as.empty() || bs.empty()) return {};
  const int len = as.size() + bs.size() - 1;
  int n = 1;
  for (; n < len; n <<= 1) {}
  as.resize(n); fft(as);
  bs.resize(n); fft(bs);
  for (int i = 0; i < n; ++i) as[i] *= bs[i];
  invFft(as);
  as.resize(len);
  return as;
}
vector<Mint> square(vector<Mint> as) {
  if (as.empty()) return {};
  const int len = as.size() + as.size() - 1;
  int n = 1;
  for (; n < len; n <<= 1) {}
  as.resize(n); fft(as);
  for (int i = 0; i < n; ++i) as[i] *= as[i];
  invFft(as);
  as.resize(len);
  return as;
}
////////////////////////////////////////////////////////////////////////////////


#ifdef LOCAL
constexpr int B = 3;
#else
constexpr int B = 400;
#endif

constexpr int V = 9;

int M;
int C[110], D[110];
Mint W[110];
int N, K;

vector<Mint> baby[B + 1][V][V];

int main() {
  for (; ~scanf("%d", &M); ) {
    for (int m = 0; m < M; ++m) {
      scanf("%d%d%u", &C[m], &D[m], &W[m].x);
    }
    scanf("%d%d", &N, &K);
    
    for (int n = 0; n <= B; ++n) {
      const int off = n + (V - 1);
      for (int u = 0; u < V; ++u) for (int v = 0; v < V; ++v) {
        baby[n][u][v].assign(off + 1 + off, 0);
      }
    }
    for (int u = 0; u < V; ++u) {
      baby[0][u][u][V - 1] += 1;
    }
    for (int u = 0; u < V - 1; ++u) {
      baby[1][u][u + 1][V] += 1;
    }
    for (int m = 0; m < M; ++m) {
      baby[1][C[m] - 1][0][V + D[m]] += W[m];
    }
    
    for (int n = 2; n <= B; ++n) {
      const int off = n + (V - 1);
      const int off1 = (n - 1) + (V - 1);
      for (int u = 0; u < V; ++u) for (int v = 0; v < V; ++v) for (int w = 0; w < V; ++w) if (v + 1 == w || w == 0) {
        for (int l = -V; l <= V; ++l) if (baby[1][v][w][V + l]) {
          for (int k = -off1; k <= off1; ++k) if (baby[n - 1][u][v][off1 + k]) {
            baby[n][u][w][off + (k + l)] += baby[n - 1][u][v][off1 + k] * baby[1][v][w][V + l];
          }
        }
      }
    }
// for(int n=0;n<=B;++n){cerr<<n<<": "<<baby[n][0][0]<<endl;}
    
    const int lim = (N/B) * (B + (V - 1));
    int len = 1;
    for (; len < lim + 1 + lim; len <<= 1) {}
    
    vector<Mint> fss[V][V], gss[V], hss[V], tail[V];
    for (int u = 0; u < V; ++u) for (int v = 0; v < V; ++v) {
      fss[u][v] = baby[B][u][v];
      fss[u][v].resize(len, 0);
      fft(fss[u][v]);
    }
    for (int u = 0; u < V; ++u) {
      gss[u].assign(len, 1);
      hss[u].assign(len, 0);
      tail[u].assign(len + 1, 0);
      tail[u][0] = 1;
    }
    
    vector<Mint> ans(N + 1, 0);
    for (int q = 0; q <= N; q += B) {
      const int offQ = (q/B) * (B + (V - 1));
      for (int r = 0; r < B && q + r <= N; ++r) {
        const int offR = r + (V - 1);
        for (int u = 0; u < V; ++u) for (int k = -offR; k <= +offR; ++k) {
          ans[q + r] += tail[u][min(max(offQ + (K - k), 0), len)] * baby[r][u][0][offR + k];
        }
      }
      for (int u = 0; u < V; ++u) {
        fill(hss[u].begin(), hss[u].end(), 0);
      }
      for (int u = 0; u < V; ++u) for (int v = 0; v < V; ++v) {
        for (int i = 0; i < len; ++i) {
          hss[v][i] += gss[u][i] * fss[u][v][i];
        }
      }
      for (int u = 0; u < V; ++u) {
        copy(hss[u].begin(), hss[u].end(), gss[u].begin());
        invFft(hss[u]);
        for (int i = len; --i >= 0; ) {
          tail[u][i] = hss[u][i] + tail[u][i + 1];
        }
      }
    }
    
    for (int n = 1; n <= N; ++n) {
      printf("%u\n", ans[n].x);
    }
  }
  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 8ms
memory: 58272kb

input:

1
1 1 2
5 2

output:

0
4
8
16
32

result:

ok 5 number(s): "0 4 8 16 32"

Test #2:

score: 0
Accepted
time: 11ms
memory: 58268kb

input:

2
1 -1 1
1 1 2
4 2

output:

0
4
8
48

result:

ok 4 number(s): "0 4 8 48"

Test #3:

score: -100
Wrong Answer
time: 239ms
memory: 58520kb

input:

99
1 -1 4155
1 0 1361
1 1 5264
2 -2 1903
2 -1 3676
2 0 9643
2 1 6909
2 2 4902
3 -3 3561
3 -2 8489
3 -1 4948
3 0 1282
3 1 3653
3 2 674
3 3 2220
4 -4 5402
4 -3 6923
4 -2 3831
4 -1 9369
4 0 3878
4 1 259
4 2 9008
4 3 2619
4 4 3971
5 -5 3
5 -4 1945
5 -3 9781
5 -2 6504
5 -1 2392
5 0 2685
5 1 5313
5 2 6698...

output:

234766
624016950
888951602
883823717
812050483
386395815
904584746
79948848
624302139
441897336
864627861
239860919
600158382
9345913
950759031
808876429
324717166
544896677
310558
845885672
604693446
363307003
706133160
301907301
187439508
807730354
301969698
530408135
660118471
622887093
933985212...

result:

wrong answer 1st numbers differ - expected: '6625', found: '234766'