Submission #73376492
Source Code Expand
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <chrono>
#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 T> ostream &operator<<(ostream &os, const vector<T> &as);
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 = 998244353;
using Mint = ModInt<MO>;
vector<Mint> findLinearRecurrence(const vector<Mint> &as) {
const int n = as.size();
int d = 0, m = 0;
vector<Mint> cs(n + 1, 0), bs(n + 1, 0);
cs[0] = bs[0] = 1;
Mint invBef = 1;
for (int i = 0; i < n; ++i) {
++m;
Mint dif = as[i];
for (int j = 1; j < d + 1; ++j) dif += cs[j] * as[i - j];
if (dif.x != 0) {
auto csDup = cs;
const Mint r = dif * invBef;
for (int j = m; j < n; ++j) cs[j] -= r * bs[j - m];
if (2 * d <= i) {
d = i + 1 - d;
m = 0;
bs = csDup;
invBef = dif.inv();
}
}
}
cs.resize(d + 1);
return cs;
}
// x^e mod rev(cs)
vector<Mint> powerRev(const vector<Mint> &cs, Int e) {
assert(!cs.empty());
assert(cs[0] == 1);
const int d = (int)cs.size() - 1;
if (d == 0) return {};
if (d == 1) return {(-cs[1]).pow(e)};
auto mul = [&](const vector<Mint> &fs, const vector<Mint> &gs) {
vector<Mint> hs(d + d - 1, 0);
for (int i = 0; i < d; ++i) for (int j = 0; j < d; ++j) {
hs[i + j] += fs[i] * gs[j];
}
for (int i = d + d - 1; --i >= d; ) {
for (int j = 1; j <= d; ++j) {
hs[i - j] -= cs[j] * hs[i];
}
}
hs.resize(d);
return hs;
};
vector<Mint> xs(d, 0), ys(d, 0);
xs[1] = 1;
ys[0] = 1;
for (; ; xs = mul(xs, xs)) {
if (e & 1) ys = mul(ys, xs);
if (!(e >>= 1)) break;
}
return ys;
}
Mint linearRecurrenceAt(const vector<Mint> &as, const vector<Mint> &cs, Int e) {
assert(!cs.empty());
assert(cs[0] == 1);
const int d = (int)cs.size() - 1;
assert((int)as.size() >= d);
const auto fs = powerRev(cs, e);
Mint ans = 0;
for (int i = 0; i < d; ++i) {
ans += fs[i] * as[i];
}
return ans;
}
// [l, r)^n
template <class F> void doArraysRec(int n, int l, int r, F f, int i, vector<int> &as) {
if (i == n) {
f(as);
} else {
for (as[i] = l; as[i] < r; ++as[i]) doArraysRec(n, l, r, f, i + 1, as);
}
}
template <class F> void doArrays(int n, int l, int r, F f) {
vector<int> as(n);
doArraysRec(n, l, r, f, 0, as);
}
template <class String>
vector<pair<int, int>> lyndonSuffix(const String &as) {
const int n = as.size();
vector<pair<int, int>> pqs(n + 1);
pqs[0] = make_pair(0, 0);
for (int u = 0; u < n; ) {
for (int p = 1, q = 1, r = 0, v = u + 1; ; ++v) {
// as[u, v) = as[u, u + p)^q as[u, u + r)
// as[u, u + p): Lyndon
pqs[v] = (r != 0) ? pqs[u + r] : make_pair(p, q);
if (v == n || as[v - p] > as[v]) {
u = v - r;
break;
} else if (as[v - p] < as[v]) {
p = v + 1 - u; q = 1; r = 0;
} else {
if (++r == p) { ++q; r = 0; }
}
}
}
return pqs;
}
/*
c(i) = A[0,i) b A[i,N)
for i < j,
cmp(c(i), c(j))
= cmp(b A[i,j), A[i,j) b)
= cmp(b^INF, A[i,j)^INF)
c(0) <= c(1), ..., c(N) <=> b^INF <= \min[0<j<=N] A[0,j)^INF
c(0), ..., c(N-1) > c(N) <=> b^INF > \max[0<=i<N] A[i,N)^INF
j: minimize A[0,j)^INF
tie-break min j
Claim. c(1), ..., c(j-1) is not opt.
assume:
0 < i < j
c(0) > c(i)
c(i) <= c(j)
b^INF > A[0,j)^INF
b^INF <= A[i,j)^INF
A[0,j)^INF < A[i,j)^INF
A[0,j)^INF < A[0,i)^INF
(st)^INF < s^INF
(st)^INF < t^INF
sts < sst
stt < tst
ts < st
st < ts
contradiction
i: maximize A[i,N)^INF
tie-break: max i
Claim. c(i+1), ..., c(N-1) is not opt.
assume:
i < j < N
c(i) > c(j)
c(i) <= c(N)
b^INF > A[i,j)^INF
b^INF <= A[i,N)^INF
A[i,j)^INF < A[i,N)^INF
A[j,N)^INF < A[i,N)^INF
s^INF < (st)^INF
t^INF < (st)^INF
sst < sts
tst < stt
st < ts
ts < ts
contradiction
Claim. equivalent to minimizing (-A)[i,N)
take i: minimize (-A)[i,N)
want to prove (-A)[i,N)^INF <= (-A)[j,N)^INF
only hard case: (-A)[i,N) is prefix of (-A)[j,N)
j < i < N
(-A)[i,N) = s
(-A)[j,N) = st
s^INF <= (st)^INF <=> sst <= sts <=> st <= ts <=> s^INF <= t^INF
induct on j
counting problem:
for each A[l,r) in the decomposition
count b s.t.
1 <= |b| <= M
b^INF > A[l,r)^INF
a := A[l,r)
Case. |b| < |a|
Case. LCP(b, a) < |b|
condition: b > a[0, |b|)
Case. LCP(b, a) = |b|
always b^INF > a^INF by the decomposition
Case. |b| >= |a|
Case. LCP(b, a) < |a|
condition: b[0, |a|) > a
Case. LCP(b, a) >= |a|
b = as
(as)^INF > a^INF <=> asa > aas <=> sa > as <=> s^INF > a^INF
reduced to |b|-|a|
*/
int N;
Int M, K;
vector<Int> A;
int main() {
// getCutsStress(); return 0;
for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
scanf("%d%lld%lld", &N, &M, &K);
A.resize(N);
for (int i = 0; i < N; ++i) scanf("%lld", &A[i]);
vector<Int> negA(N);
for (int i = 0; i < N; ++i) negA[i] = -A[i];
const auto pqs = lyndonSuffix(negA);
vector<int> cuts{N};
for (int i = N; i > 0; ) {
const int p = pqs[i].first;
const int q = pqs[i].second;
for (int j = q; --j >= 0; ) cuts.push_back(i -= p);
}
reverse(cuts.begin(), cuts.end());
const int len = (int)cuts.size() - 1;
//cerr<<"cuts = "<<cuts<<endl;
vector<Mint> ways(len, 0);
for (int h = 0; h < len; ++h) {
const int l = cuts[h], r = cuts[h + 1];
const int m = r - l;
vector<Mint> fs(m + 1, 0);
for (int i = 0; i < m; ++i) fs[i + 1] = fs[i] * K + (K - A[l + i]);
//cerr<<vector<Int>(A.begin()+l,A.begin()+r)<<": "<<fs<<endl;
for (int i = 0; i < m && i <= M; ++i) {
// |b| = i, m+i, 2m+i, ... <= M
constexpr int LEN = 10;
vector<Mint> gs(LEN);
gs[0] = fs[i] + (i ? 1 : 0);
for (int j = 1; j < LEN; ++j) gs[j] = fs[m] * Mint(K).pow((j-1) * m + i) + gs[j - 1];
for (int j = 1; j < LEN; ++j) gs[j] += gs[j - 1];
//cerr<<" "<<i<<": "<<gs<<endl;
const auto cs = findLinearRecurrence(gs);
ways[h] += linearRecurrenceAt(gs, cs, (M - i) / m);
}
}
//cerr<<"ways = "<<ways<<endl;
Mint all;
{
Mint k = K;
all = (k == 1) ? M : ((k.pow(M+1) - k) / (k - 1));
}
vector<Mint> ans(N + 1, 0);
for (int h = 0; h <= len; ++h) {
ans[cuts[h]] = ((h == 0) ? all : ways[h - 1]) - ((h == len) ? 0 : ways[h]);
}
for (int i = 0; i <= N; ++i) {
if (i) printf(" ");
printf("%u", ans[i].x);
}
puts("");
}
#ifndef LOCAL
break;
#endif
}
return 0;
}
Submission Info
| Submission Time |
|
| Task |
C - Addictive Addition |
| User |
hos_lyric |
| Language |
C++ IOI-Style(GNU++20) (GCC 14.2.0) |
| Score |
100 |
| Code Size |
10664 Byte |
| Status |
AC |
| Exec Time |
1307 ms |
| Memory |
23120 KiB |
Compile Error
Main.cpp: In function ‘int main()’:
Main.cpp:278:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
278 | scanf("%d%lld%lld", &N, &M, &K);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:280:38: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
280 | for (int i = 0; i < N; ++i) scanf("%lld", &A[i]);
| ~~~~~^~~~~~~~~~~~~~~
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
100 / 100 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
example_00.txt |
| All |
example_00.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt, test_56.txt, test_57.txt, test_58.txt, test_59.txt, test_60.txt, test_61.txt, test_62.txt, test_63.txt, test_64.txt, test_65.txt, test_66.txt, test_67.txt, test_68.txt, test_69.txt, test_70.txt, test_71.txt, test_72.txt, test_73.txt, test_74.txt, test_75.txt, test_76.txt, test_77.txt, test_78.txt, test_79.txt, test_80.txt, test_81.txt, test_82.txt, test_83.txt, test_84.txt, test_85.txt, test_86.txt, test_87.txt, test_88.txt, test_89.txt |
| Case Name |
Status |
Exec Time |
Memory |
| example_00.txt |
AC |
0 ms |
1708 KiB |
| test_00.txt |
AC |
396 ms |
7184 KiB |
| test_01.txt |
AC |
310 ms |
4560 KiB |
| test_02.txt |
AC |
292 ms |
3484 KiB |
| test_03.txt |
AC |
239 ms |
2508 KiB |
| test_04.txt |
AC |
283 ms |
2736 KiB |
| test_05.txt |
AC |
156 ms |
1708 KiB |
| test_06.txt |
AC |
68 ms |
1708 KiB |
| test_07.txt |
AC |
259 ms |
2232 KiB |
| test_08.txt |
AC |
260 ms |
2248 KiB |
| test_09.txt |
AC |
259 ms |
2216 KiB |
| test_10.txt |
AC |
348 ms |
3764 KiB |
| test_11.txt |
AC |
349 ms |
3772 KiB |
| test_12.txt |
AC |
348 ms |
3784 KiB |
| test_13.txt |
AC |
1141 ms |
3744 KiB |
| test_14.txt |
AC |
1168 ms |
3756 KiB |
| test_15.txt |
AC |
1145 ms |
3824 KiB |
| test_16.txt |
AC |
1064 ms |
3740 KiB |
| test_17.txt |
AC |
1060 ms |
3756 KiB |
| test_18.txt |
AC |
1078 ms |
3756 KiB |
| test_19.txt |
AC |
938 ms |
15500 KiB |
| test_20.txt |
AC |
918 ms |
15628 KiB |
| test_21.txt |
AC |
932 ms |
15440 KiB |
| test_22.txt |
AC |
930 ms |
15492 KiB |
| test_23.txt |
AC |
917 ms |
15892 KiB |
| test_24.txt |
AC |
1169 ms |
23120 KiB |
| test_25.txt |
AC |
1141 ms |
23120 KiB |
| test_26.txt |
AC |
1152 ms |
23116 KiB |
| test_27.txt |
AC |
1307 ms |
23112 KiB |
| test_28.txt |
AC |
1302 ms |
23112 KiB |
| test_29.txt |
AC |
1296 ms |
22868 KiB |
| test_30.txt |
AC |
875 ms |
15416 KiB |
| test_31.txt |
AC |
751 ms |
15420 KiB |
| test_32.txt |
AC |
964 ms |
15416 KiB |
| test_33.txt |
AC |
769 ms |
15420 KiB |
| test_34.txt |
AC |
793 ms |
15416 KiB |
| test_35.txt |
AC |
1001 ms |
15504 KiB |
| test_36.txt |
AC |
985 ms |
15488 KiB |
| test_37.txt |
AC |
969 ms |
15548 KiB |
| test_38.txt |
AC |
712 ms |
15468 KiB |
| test_39.txt |
AC |
1000 ms |
15424 KiB |
| test_40.txt |
AC |
753 ms |
15428 KiB |
| test_41.txt |
AC |
1070 ms |
20304 KiB |
| test_42.txt |
AC |
969 ms |
16048 KiB |
| test_43.txt |
AC |
982 ms |
15500 KiB |
| test_44.txt |
AC |
897 ms |
15540 KiB |
| test_45.txt |
AC |
1000 ms |
15520 KiB |
| test_46.txt |
AC |
881 ms |
15420 KiB |
| test_47.txt |
AC |
943 ms |
15416 KiB |
| test_48.txt |
AC |
978 ms |
15416 KiB |
| test_49.txt |
AC |
755 ms |
15416 KiB |
| test_50.txt |
AC |
929 ms |
15420 KiB |
| test_51.txt |
AC |
1069 ms |
23116 KiB |
| test_52.txt |
AC |
1183 ms |
17496 KiB |
| test_53.txt |
AC |
1182 ms |
15660 KiB |
| test_54.txt |
AC |
1094 ms |
15404 KiB |
| test_55.txt |
AC |
928 ms |
15404 KiB |
| test_56.txt |
AC |
1038 ms |
19392 KiB |
| test_57.txt |
AC |
1067 ms |
19388 KiB |
| test_58.txt |
AC |
1094 ms |
19380 KiB |
| test_59.txt |
AC |
1007 ms |
19392 KiB |
| test_60.txt |
AC |
1084 ms |
19392 KiB |
| test_61.txt |
AC |
1067 ms |
19392 KiB |
| test_62.txt |
AC |
1091 ms |
19396 KiB |
| test_63.txt |
AC |
1019 ms |
19392 KiB |
| test_64.txt |
AC |
1088 ms |
19392 KiB |
| test_65.txt |
AC |
1040 ms |
19392 KiB |
| test_66.txt |
AC |
931 ms |
15416 KiB |
| test_67.txt |
AC |
882 ms |
15420 KiB |
| test_68.txt |
AC |
971 ms |
15420 KiB |
| test_69.txt |
AC |
897 ms |
15420 KiB |
| test_70.txt |
AC |
894 ms |
15420 KiB |
| test_71.txt |
AC |
1125 ms |
19468 KiB |
| test_72.txt |
AC |
1110 ms |
19388 KiB |
| test_73.txt |
AC |
983 ms |
19392 KiB |
| test_74.txt |
AC |
1176 ms |
19396 KiB |
| test_75.txt |
AC |
1126 ms |
19388 KiB |
| test_76.txt |
AC |
962 ms |
16564 KiB |
| test_77.txt |
AC |
969 ms |
16160 KiB |
| test_78.txt |
AC |
1059 ms |
15532 KiB |
| test_79.txt |
AC |
1043 ms |
15404 KiB |
| test_80.txt |
AC |
1181 ms |
15532 KiB |
| test_81.txt |
AC |
930 ms |
15548 KiB |
| test_82.txt |
AC |
944 ms |
15580 KiB |
| test_83.txt |
AC |
801 ms |
15420 KiB |
| test_84.txt |
AC |
872 ms |
15672 KiB |
| test_85.txt |
AC |
965 ms |
15548 KiB |
| test_86.txt |
AC |
969 ms |
15936 KiB |
| test_87.txt |
AC |
932 ms |
16376 KiB |
| test_88.txt |
AC |
880 ms |
15644 KiB |
| test_89.txt |
AC |
998 ms |
15388 KiB |