QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#170462 | #7187. Hardcore String Counting | ucup-team1477# | AC ✓ | 372ms | 14644kb | C++17 | 9.3kb | 2023-09-09 15:19:23 | 2023-09-09 15:19:24 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
// code below from https://judge.yosupo.jp/submission/59871
namespace solver {
const int mod = 998244353;
template<int mod>
struct NTT {
static constexpr int max_lev = __builtin_ctz(mod - 1);
int prod[2][max_lev - 1];
NTT() {
int root = (mod == 998244353) ? 31 : find_root();
int rroot = inv(root);
vector<vector<int>> roots(2, vector<int>(max_lev - 1));
roots[0][max_lev - 2] = root;
roots[1][max_lev - 2] = rroot;
for (int tp = 0; tp < 2; ++tp) {
for (int i = max_lev - 3; i >= 0; --i) {
roots[tp][i] = mul(roots[tp][i + 1], roots[tp][i + 1]);
}
}
for (int tp = 0; tp < 2; ++tp) {
int cur = 1;
for (int i = 0; i < max_lev - 1; ++i) {
prod[tp][i] = mul(cur, roots[tp][i]);
cur = mul(cur, roots[tp ^ 1][i]);
}
}
}
template<bool inverse>
void fft(int *a, int lg) const {
const int n = 1 << lg;
int pos = max_lev - 1;
for (int it = 0; it < lg; ++it) {
const int h = inverse ? lg - 1 - it : it;
const int shift = (1 << (lg - h - 1));
int coef = 1;
for (int start = 0; start < (1 << h); ++start) {
for (int i = start << (lg - h); i < (start << (lg - h)) + shift; ++i) {
if (!inverse) {
const int y = mul(a[i + shift], coef);
a[i + shift] = a[i];
inc(a[i], y);
dec(a[i + shift], y);
} else {
const int y = mul(a[i] + mod - a[i + shift], coef);
inc(a[i], a[i + shift]);
a[i + shift] = y;
}
}
coef = mul(coef, prod[inverse][__builtin_ctz(~start)]);
}
}
if (inverse) {
const int rn = inv(n);
for (int i = 0; i < n; ++i) {
a[i] = mul(a[i], rn);
}
}
}
vector<int> product(vector<int> a, vector<int> b) const {
if (a.empty() || b.empty()) {
return {};
}
const int sz = a.size() + b.size() - 1;
const int lg = 32 - __builtin_clz(sz - 1), n = 1 << lg;
a.resize(n);
b.resize(n);
fft<false>(a.data(), lg);
fft<false>(b.data(), lg);
for (int i = 0; i < n; ++i) {
a[i] = mul(a[i], b[i]);
}
fft<true>(a.data(), lg);
a.resize(sz);
return a;
}
vector<int> square(vector<int> a) const {
if (a.empty()) {
return {};
}
const int sz = a.size() + a.size() - 1;
const int lg = 32 - __builtin_clz(sz - 1), n = 1 << lg;
a.resize(n);
fft<false>(a.data(), lg);
for (int i = 0; i < n; ++i) {
a[i] = mul(a[i], a[i]);
}
fft<true>(a.data(), lg);
a.resize(sz);
return a;
}
static int find_root() {
for (int root = 2; ; ++root) {
if (power(root, (1 << max_lev)) == 1 && power(root, (1 << (max_lev - 1))) != 1) {
return root;
}
}
}
static inline void inc(int &x, int y) {
x += y;
if (x >= mod) {
x -= mod;
}
}
static inline void dec(int &x, int y) {
x -= y;
if (x < 0) {
x += mod;
}
}
static inline int mul(int x, int y) {
return (1LL * x * y) % mod;
}
static int power(int x, int y) {
if (y == 0) {
return 1;
}
if (y % 2 == 0) {
return power(mul(x, x), y / 2);
}
return mul(x, power(x, y - 1));
}
static int inv(int x) {
return power(x, mod - 2);
}
};
NTT<mod> ntt;
vector<int> trim(const vector<int> &v, size_t n) {
return {v.begin(), v.begin() + min(n, v.size())};
}
vector<int> inv(const vector<int> &p, int n) {
assert(!p.empty() && p[0]);
vector<int> q{ntt.inv(p[0])};
while (q.size() < n) {
const int need = min<int>(2 * q.size(), n);
vector<int> a(2 * q.size()), b(2 * q.size());
copy(q.begin(), q.end(), a.begin());
copy(p.begin(), p.begin() + min<int>(need, p.size()), b.begin());
ntt.fft<false>(a.data(), __builtin_ctz(2 * q.size()));
ntt.fft<false>(b.data(), __builtin_ctz(2 * q.size()));
for (int i = 0; i < b.size(); ++i) { // calculating (pq-1)/(x^|q|), using pq = 1000????
b[i] = ntt.mul(b[i], a[i]);
ntt.dec(b[i], 1);
if (i >= q.size()) {
b[i] = mod - (b[i] ? b[i] : mod);
}
}
ntt.fft<true>(b.data(), __builtin_ctz(2 * q.size()));
fill(b.begin() + q.size(), b.end(), 0);
ntt.fft<false>(b.data(), __builtin_ctz(2 * q.size()));
for (int i = 0; i < b.size(); ++i) {
b[i] = ntt.mul(b[i], a[i]);
}
ntt.fft<true>(b.data(), __builtin_ctz(2 * q.size()));
const int old_sz = q.size();
q.resize(need);
for (int i = old_sz; i < need; ++i) {
q[i] = mod - (b[i - old_sz] ? b[i - old_sz] : mod);
}
}
return q;
}
void ntt_doubling(vector<int> &v) {
const int m = v.size();
vector<int> f = v;
ntt.fft<true>(f.data(), __builtin_ctz(f.size()));
int coef = 1;
const int zeta = ntt.power(ntt.find_root(), (1 << ntt.max_lev) / (2 * m));
for (int i = 0; i < m; ++i) {
f[i] = ntt.mul(f[i], coef);
coef = ntt.mul(coef, zeta);
}
ntt.fft<false>(f.data(), __builtin_ctz(f.size()));
v.resize(2 * m);
for (int i = 0; i < m; ++i) {
v[i + m] = f[i];
}
}
int poly_coeff(vector<int> Q, vector<int> P, long long n) {
int m = 1;
while (m < Q.size()) {
m <<= 1;
}
P.resize(2 * m);
Q.resize(2 * m);
ntt.fft<false>(P.data(), __builtin_ctz(P.size()));
ntt.fft<false>(Q.data(), __builtin_ctz(Q.size()));
vector<int> S(2 * m), T(2 * m);
vector<int> btr(m);
for (int i = 0, logn = __builtin_ctz(m); i < m; ++i) {
btr[i] = (btr[i >> 1] >> 1) + ((i & 1) << (logn - 1));
}
const int dw = ntt.power(ntt.inv(ntt.find_root()), (1 << ntt.max_lev) / (2 * m));
while (n) {
int inv2 = (mod + 1) / 2;
S.resize(m);
T.resize(m);
for (int i = 0; i < m; i++) {
T[i] = ntt.mul(Q[2 * i], Q[2 * i + 1]);
}
if (n & 1) {
for (auto &i : btr) {
S[i] = ntt.mul(ntt.mul(P[2 * i], Q[2 * i + 1]) + mod - ntt.mul(P[2 * i + 1], Q[2 * i]), inv2);
inv2 = ntt.mul(inv2, dw);
}
} else {
for (int i = 0; i < m; ++i) {
S[i] = ntt.mul(ntt.mul(P[2 * i], Q[2 * i + 1]) + ntt.mul(P[2 * i + 1], Q[2 * i]), inv2);
}
}
swap(P, S);
swap(Q, T);
n >>= 1;
if (n < m) {
break;
}
ntt_doubling(P);
ntt_doubling(Q);
}
ntt.fft<true>(P.data(), __builtin_ctz(P.size()));
ntt.fft<true>(Q.data(), __builtin_ctz(Q.size()));
return ntt.product(P, inv(Q, n + 1))[n];
}
// returns a[k], where a[i] = sum j=1..d (c[j]*a[i-j]), d=|c|
int kth_term_of_LRS(vector<int> a, vector<int> c, long long k) {
assert(a.size() == c.size());
for (int &x : c) {
x = (mod - x) % mod;
}
c.insert(c.begin(), 1);
a = trim(ntt.product(a, c), a.size());
return poly_coeff(c, a, k);
}
const bool debug = 0;
int main(int n, long long k, vector<int> a, vector<int> c) {
return kth_term_of_LRS(a, c, k);
}
} // namespace solver
constexpr int P = 998244353;
template <class T> T qp(T a, int b) {
T c{1};
for (; b; b /= 2, a *= a) {
if (b % 2) {
c *= a;
}
}
return c;
}
struct mint {
int x;
mint(int _x = 0) : x(_x % P) { x < 0 ? x += P : 0; }
int val() const { return x; }
mint operator - () const {
return -x;
}
mint inv() const {
assert(x != 0);
return qp(*this, P - 2);
}
mint &operator += (const mint &rhs) {
x += rhs.x - P, x += x >> 31 & P;
return *this;
}
mint &operator -= (const mint &rhs) {
x -= rhs.x, x += x >> 31 & P;
return *this;
}
mint &operator *= (const mint &rhs) {
x = (long long)x * rhs.x % P;
return *this;
}
mint &operator /= (const mint &rhs) {
return *this *= rhs.inv();
}
friend mint operator + (mint lhs, const mint &rhs) {
return lhs += rhs;
}
friend mint operator - (mint lhs, const mint &rhs) {
return lhs -= rhs;
}
friend mint operator * (mint lhs, const mint &rhs) {
return lhs *= rhs;
}
friend mint operator / (mint lhs, const mint &rhs) {
return lhs /= rhs;
}
friend ostream &operator << (ostream &os, const mint &a) {
return os << a.val();
}
};
struct _comb {
int n;
vector<mint> _fact, _finv, _inv;
_comb() : n{0}, _fact{1}, _finv{1}, _inv{0} {}
_comb(int n) : _comb() { init(n); }
void init(int m) {
if (m <= n) return;
_fact.resize(m + 1);
_finv.resize(m + 1);
_inv.resize(m + 1);
for (int i = n + 1; i <= m; i++) {
_fact[i] = _fact[i - 1] * i;
}
_finv[m] = _fact[m].inv();
for (int i = m; i > n; i--) {
_finv[i - 1] = _finv[i] * i;
_inv[i] = _finv[i] * _fact[i - 1];
}
n = m;
}
mint fact(int m) {
if (m > n) init(2 * m);
return _fact[m];
}
mint finv(int m) {
if (m > n) init(2 * m);
return _finv[m];
}
mint inv(int m) {
if (m > n) init(2 * m);
return _inv[m];
}
mint binom(int n, int m) {
if (n < m || m < 0) return 0;
return fact(n) * finv(m) * finv(n - m);
}
} comb;
constexpr int sigma = 26;
int main() {
ios::sync_with_stdio(0), cin.tie(0);
int n, m;
string s;
cin >> n >> m >> s;
vector<int> pi(n);
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j && s[i] != s[j]) {
j = pi[j - 1];
}
if (s[i] == s[j]) {
j++;
}
pi[i] = j;
}
vector<bool> border(n + 1);
for (int i = n; i; i = pi[i - 1]) {
border[i] = 1;
}
const mint p = mint(sigma).inv();
vector<mint> coef(n + 1);
coef[1] = 1;
coef[n] -= qp(p, n);
for (int k = 1; k < n; k++) {
if (border[n - k]) {
coef[k] -= qp(p, k);
coef[k + 1] += qp(p, k);
}
}
vector<int> a(n), c(n);
a.back() = qp(p, n).val();
for (int i = 0; i < n; i++) {
c[i] = coef[i + 1].val();
}
cout << solver::main(n, m - 1, a, c) * qp(mint(sigma), m) << "\n";
return 0;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3668kb
input:
6 7 aaaaaa
output:
25
result:
ok answer is '25'
Test #2:
score: 0
Accepted
time: 1ms
memory: 3700kb
input:
3 5 aba
output:
675
result:
ok answer is '675'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3668kb
input:
1 1 a
output:
1
result:
ok answer is '1'
Test #4:
score: 0
Accepted
time: 1ms
memory: 3608kb
input:
5 7 ababa
output:
675
result:
ok answer is '675'
Test #5:
score: 0
Accepted
time: 1ms
memory: 3552kb
input:
1 3 a
output:
625
result:
ok answer is '625'
Test #6:
score: 0
Accepted
time: 1ms
memory: 3604kb
input:
10 536870912 njjnttnjjn
output:
826157401
result:
ok answer is '826157401'
Test #7:
score: 0
Accepted
time: 157ms
memory: 9300kb
input:
65535 536870912 aaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaraaaoaaaoaaaoaaayaaaoaaaoaaao...
output:
996824286
result:
ok answer is '996824286'
Test #8:
score: 0
Accepted
time: 326ms
memory: 14612kb
input:
99892 536870912 wwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwwawwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwwawwwwbwwwwb...
output:
718505966
result:
ok answer is '718505966'
Test #9:
score: 0
Accepted
time: 327ms
memory: 14536kb
input:
100000 536870912 rrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrttrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrarrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrm...
output:
824845147
result:
ok answer is '824845147'
Test #10:
score: 0
Accepted
time: 341ms
memory: 14532kb
input:
99892 1000000000 ggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggbggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggbggggjgggg...
output:
971128221
result:
ok answer is '971128221'
Test #11:
score: 0
Accepted
time: 275ms
memory: 14272kb
input:
100000 625346716 kwfuguxrbiwlvyqsbujelgcafpsnxsgefwxqoeeiwoolreyxvaahagoibdrznebsgelthdzqwxcdglvbpawhdgaxpiyjglzhiamhtptsyyzyyhzjvnqfyqhnrtbwgeyotmltodidutmyvzfqfctnqugmrdtuyiyttgcsjeupuuygwqrzfibxhaefmbtzfhvopmtwwycopheuacgwibxlsjpupdmchvzneodwuzzteqlzlfizpleildqqpcuiechcwearxlvplatyrzxfochdfjqcmzt...
output:
0
result:
ok answer is '0'
Test #12:
score: 0
Accepted
time: 191ms
memory: 12956kb
input:
65536 35420792 pkmyknsqmhwuevibxjgrftrinkulizarxbkmgorddvuvtrhdadnlxfrxsyqhueuefdkanysaixmhbdqyskjdrzntlaqtwoscxldmyzahzwximvjgsjuddejbsbwtxgkbzfzdusucccohjwjuaasnkindxjjtxdbxmitcixrcmawdezafgnigghdtoyzazyfedzsuwsrlkdtarcmzqnszgnyiqvzamjtamvfrhzucdsfscyzdbvbxutwraktnmfrdfbejcbhjcgczgwiucklwydmuuozlu...
output:
0
result:
ok answer is '0'
Test #13:
score: 0
Accepted
time: 372ms
memory: 14528kb
input:
100000 1000000000 nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn...
output:
545362217
result:
ok answer is '545362217'
Test #14:
score: 0
Accepted
time: 358ms
memory: 14644kb
input:
100000 536870911 ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg...
output:
332737929
result:
ok answer is '332737929'
Test #15:
score: 0
Accepted
time: 269ms
memory: 14620kb
input:
100000 536870911 qodtwstdnykduvzvvvzmpawqaajvcdatuzzjisoezaqtvqhghmixvlfyhznvrlhdslyyhxoqchflfdjiefikpfrykekhjqywxpwmihiojcfzcmqelrkddbpkcnqcaopdyhldawyrvkqfbqpybewrtusifbfdtxiflxtkzdjqbocozdpupunehraytkhqnobhzeohkvbjyrdfebstqfjlvrcabimlybsnuaqgfcldvklwnyuywvfpdqwmortctexzaufmazyatybltglyonllufofiyr...
output:
592710827
result:
ok answer is '592710827'
Test #16:
score: 0
Accepted
time: 65ms
memory: 14536kb
input:
100000 100000 ciawhxojdqnivfonswbklnoocigwmkbjtkzahqgysihfdeqhialusobeeazqaqzryakqycapfswxpithldpuiflxzpgsysjwnpinfubqlyadphswzvzbrxcdbbhavtzkvwrcqecfnzawisgkvsopjnfzfnlecuesnffqzcknunwsxlrbvdzqbduypfrwgqqnrjstxgjaeuqxxajfbmidkwhrgkpjduftivfwnuugxomyznpbtbcstdkdaitvpdtuvyzipygztosvjwwdascbqthqdgkbit...
output:
1
result:
ok answer is '1'
Test #17:
score: 0
Accepted
time: 292ms
memory: 14536kb
input:
100000 1000000000 zujpixywgppdzqtwikoyhvlwqvxrfdylopuqgprrqpgqmgfkmhbucwkgdljyfzzbtaxxnltmbptwhknjjqlbeuiowdblqppqeeuunexkghdxjtbidlacmycgwvulgaeazyiwzedaxhtskacflodouylwxfjydzfbthotdwrfcpwrkcgnxpjsmkafaaojlctmqckabidgalvptziemzphncrgtqxlvllgwwgkoqxwhziuxvkadgaohdlceuggwwzmpywsgoecwwhhbotaleesjexdxg...
output:
879141501
result:
ok answer is '879141501'
Extra Test:
score: 0
Extra Test Passed