QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#214070 | #6548. Courses | ucup-team087# | WA | 239ms | 58520kb | C++14 | 12.0kb | 2023-10-14 17:05:43 | 2023-10-14 17:05:43 |
Judging History
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'