結果
問題 | No.2626 Similar But Different Name |
ユーザー | Fu_L |
提出日時 | 2024-02-18 17:13:28 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 333 ms / 3,000 ms |
コード長 | 15,195 bytes |
コンパイル時間 | 2,775 ms |
コンパイル使用メモリ | 236,984 KB |
実行使用メモリ | 56,748 KB |
最終ジャッジ日時 | 2024-09-29 00:43:35 |
合計ジャッジ時間 | 9,385 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,820 KB |
testcase_01 | AC | 2 ms
6,820 KB |
testcase_02 | AC | 2 ms
6,820 KB |
testcase_03 | AC | 2 ms
6,816 KB |
testcase_04 | AC | 1 ms
6,816 KB |
testcase_05 | AC | 2 ms
6,820 KB |
testcase_06 | AC | 2 ms
6,816 KB |
testcase_07 | AC | 2 ms
6,820 KB |
testcase_08 | AC | 3 ms
6,820 KB |
testcase_09 | AC | 2 ms
6,816 KB |
testcase_10 | AC | 4 ms
6,820 KB |
testcase_11 | AC | 4 ms
6,816 KB |
testcase_12 | AC | 3 ms
6,816 KB |
testcase_13 | AC | 4 ms
6,816 KB |
testcase_14 | AC | 3 ms
6,820 KB |
testcase_15 | AC | 4 ms
6,816 KB |
testcase_16 | AC | 3 ms
6,820 KB |
testcase_17 | AC | 4 ms
6,820 KB |
testcase_18 | AC | 333 ms
56,720 KB |
testcase_19 | AC | 46 ms
27,600 KB |
testcase_20 | AC | 44 ms
27,640 KB |
testcase_21 | AC | 43 ms
27,640 KB |
testcase_22 | AC | 310 ms
47,300 KB |
testcase_23 | AC | 306 ms
47,356 KB |
testcase_24 | AC | 308 ms
44,880 KB |
testcase_25 | AC | 305 ms
45,812 KB |
testcase_26 | AC | 311 ms
47,380 KB |
testcase_27 | AC | 310 ms
47,480 KB |
testcase_28 | AC | 310 ms
46,320 KB |
testcase_29 | AC | 303 ms
44,652 KB |
testcase_30 | AC | 311 ms
45,808 KB |
testcase_31 | AC | 311 ms
46,696 KB |
testcase_32 | AC | 312 ms
47,380 KB |
testcase_33 | AC | 321 ms
47,520 KB |
testcase_34 | AC | 309 ms
44,944 KB |
testcase_35 | AC | 306 ms
46,856 KB |
testcase_36 | AC | 307 ms
44,764 KB |
testcase_37 | AC | 319 ms
56,748 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; using P = pair<ll, ll>; #define rep(i, a, b) for(ll i = a; i < b; ++i) #define rrep(i, a, b) for(ll i = a; i >= b; --i) constexpr ll inf = 4e18; struct SetupIO { SetupIO() { ios::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(30); } } setup_io; template <typename T> vector<int> z_algorithm(const vector<T>& s) { int n = (int)s.size(); if(n == 0) return {}; vector<int> z(n); z[0] = 0; for(int i = 1, j = 0; i < n; ++i) { int& k = z[i]; k = (j + z[j] <= i) ? 0 : min(j + z[j] - i, z[i - j]); while(i + k < n and s[k] == s[i + k]) ++k; if(j + z[j] < i + z[i]) j = i; } z[0] = n; return z; } vector<int> z_algorithm(const string& s) { int n = (int)s.size(); vector<int> s2(n); for(int i = 0; i < n; ++i) { s2[i] = s[i]; } return z_algorithm(s2); } template <uint32_t m> struct StaticModint { using mint = StaticModint; static constexpr uint32_t mod() { return m; } static constexpr mint raw(uint32_t v) { mint a; a._v = v; return a; } constexpr StaticModint() : _v(0) {} template <class T> constexpr StaticModint(const T& v) { static_assert(is_integral_v<T>); if constexpr(is_signed_v<T>) { int64_t x = int64_t(v % int64_t(m)); if(x < 0) x += m; _v = uint32_t(x); } else _v = uint32_t(v % m); } constexpr uint32_t val() const { return _v; } constexpr mint& operator++() { return *this += 1; } constexpr mint& operator--() { return *this -= 1; } constexpr mint operator++(int) { mint res = *this; ++*this; return res; } constexpr mint operator--(int) { mint res = *this; --*this; return res; } constexpr mint& operator+=(mint rhs) { if(_v >= m - rhs._v) _v -= m; _v += rhs._v; return *this; } constexpr mint& operator-=(mint rhs) { if(_v < rhs._v) _v += m; _v -= rhs._v; return *this; } constexpr mint& operator*=(mint rhs) { return *this = *this * rhs; } constexpr mint& operator/=(mint rhs) { return *this *= rhs.inv(); } constexpr mint operator+() const { return *this; } constexpr mint operator-() const { return mint{} - *this; } constexpr mint pow(long long n) const { assert(0 <= n); if(n == 0) return 1; mint x = *this, r = 1; while(1) { if(n & 1) r *= x; n >>= 1; if(n == 0) return r; x *= x; } } constexpr mint inv() const { if constexpr(prime) { assert(_v); return pow(m - 2); } else { auto eg = inv_gcd(_v, m); assert(eg.first == 1); return eg.second; } } friend constexpr mint operator+(mint lhs, mint rhs) { return lhs += rhs; } friend constexpr mint operator-(mint lhs, mint rhs) { return lhs -= rhs; } friend constexpr mint operator*(mint lhs, mint rhs) { return uint64_t(lhs._v) * rhs._v; } friend constexpr mint operator/(mint lhs, mint rhs) { return lhs /= rhs; } friend constexpr bool operator==(mint lhs, mint rhs) { return lhs._v == rhs._v; } friend constexpr bool operator!=(mint lhs, mint rhs) { return lhs._v != rhs._v; } friend istream& operator>>(istream& in, mint& x) { long long a; in >> a; x = a; return in; } friend ostream& operator<<(ostream& out, const mint& x) { return out << x.val(); } private: uint32_t _v = 0; static constexpr bool prime = []() -> bool { if(m == 1) return 0; if(m == 2 or m == 7 or m == 61) return 1; if(m % 2 == 0) return 0; uint32_t d = m - 1; while(d % 2 == 0) d /= 2; for(uint32_t a : {2, 7, 61}) { uint32_t t = d; mint y = mint(a).pow(t); while(t != m - 1 && y != 1 && y != m - 1) { y *= y; t <<= 1; } if(y != m - 1 && t % 2 == 0) return 0; } return 1; }(); static constexpr pair<int32_t, int32_t> inv_gcd(int32_t a, int32_t b) { if(a == 0) return {b, 0}; int32_t s = b, t = a, m0 = 0, m1 = 1; while(t) { const int32_t u = s / t; s -= t * u; m0 -= m1 * u; swap(s, t); swap(m0, m1); } if(m0 < 0) m0 += b / s; return {s, m0}; } }; using modint998244353 = StaticModint<998244353>; using modint1000000007 = StaticModint<1000000007>; constexpr ll pow_mod(ll x, ll n, ll mod) { assert(n >= 0 and mod >= 1); x %= mod; if(x < 0) x += mod; ll res = 1; while(n > 0) { if(n & 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res; } constexpr int primitive_root(int m) { if(m == 2) return 1; if(m == 167772161) return 3; if(m == 469762049) return 3; if(m == 754974721) return 11; if(m == 998244353) return 3; int divs[20] = {}; divs[0] = 2; int cnt = 1; int x = (m - 1) / 2; while(x % 2 == 0) x /= 2; for(int i = 3; (long long)(i)*i <= x; i += 2) { if(x % i == 0) { divs[cnt++] = i; while(x % i == 0) { x /= i; } } } if(x > 1) { divs[cnt++] = x; } for(int g = 2;; ++g) { bool ok = true; for(int i = 0; i < cnt; ++i) { if(pow_mod(g, (m - 1) / divs[i], m) == 1) { ok = false; break; } } if(ok) return g; } } constexpr int countr_zero(unsigned int n) { int res = 0; while(!(n & (1 << res))) ++res; return res; } template <typename mint, int g = primitive_root(mint::mod())> struct FFT_Info { static constexpr int rank2 = countr_zero(mint::mod() - 1); array<mint, rank2 + 1> root; array<mint, rank2 + 1> iroot; array<mint, max(0, rank2 - 2 + 1)> rate2; array<mint, max(0, rank2 - 2 + 1)> irate2; array<mint, max(0, rank2 - 3 + 1)> rate3; array<mint, max(0, rank2 - 3 + 1)> irate3; FFT_Info() { root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2); iroot[rank2] = root[rank2].inv(); for(int i = rank2 - 1; i >= 0; --i) { root[i] = root[i + 1] * root[i + 1]; iroot[i] = iroot[i + 1] * iroot[i + 1]; } { mint prod = 1, iprod = 1; for(int i = 0; i <= rank2 - 2; ++i) { rate2[i] = root[i + 2] * prod; irate2[i] = iroot[i + 2] * iprod; prod *= iroot[i + 2]; iprod *= root[i + 2]; } } { mint prod = 1, iprod = 1; for(int i = 0; i <= rank2 - 3; ++i) { rate3[i] = root[i + 3] * prod; irate3[i] = iroot[i + 3] * iprod; prod *= iroot[i + 3]; iprod *= root[i + 3]; } } } }; template <typename mint> void butterfly(vector<mint>& a) { int n = (int)a.size(); int h = __builtin_ctz((unsigned int)n); static const FFT_Info<mint> info; int len = 0; while(len < h) { if(h - len == 1) { int p = 1 << (h - len - 1); mint rot = 1; for(int s = 0; s < (1 << len); ++s) { int offset = s << (h - len); for(int i = 0; i < p; ++i) { auto l = a[i + offset]; auto r = a[i + offset + p] * rot; a[i + offset] = l + r; a[i + offset + p] = l - r; } if(s + 1 != (1 << len)) rot *= info.rate2[__builtin_ctz(~(unsigned int)(s))]; } ++len; } else { int p = 1 << (h - len - 2); mint rot = 1, imag = info.root[2]; for(int s = 0; s < (1 << len); ++s) { mint rot2 = rot * rot; mint rot3 = rot2 * rot; int offset = s << (h - len); for(int i = 0; i < p; ++i) { auto mod2 = 1ULL * mint::mod() * mint::mod(); auto a0 = 1ULL * a[i + offset].val(); auto a1 = 1ULL * a[i + offset + p].val() * rot.val(); auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val(); auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val(); auto a1na3imag = 1ULL * mint(a1 + mod2 - a3).val() * imag.val(); auto na2 = mod2 - a2; a[i + offset] = a0 + a2 + a1 + a3; a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3)); a[i + offset + 2 * p] = a0 + na2 + a1na3imag; a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag); } if(s + 1 != (1 << len)) rot *= info.rate3[__builtin_ctz(~(unsigned int)(s))]; } len += 2; } } } template <typename mint> void butterfly_inv(vector<mint>& a) { int n = (int)a.size(); int h = __builtin_ctz((unsigned int)n); static const FFT_Info<mint> info; int len = h; while(len) { if(len == 1) { int p = 1 << (h - len); mint irot = 1; for(int s = 0; s < (1 << (len - 1)); ++s) { int offset = s << (h - len + 1); for(int i = 0; i < p; ++i) { auto l = a[i + offset]; auto r = a[i + offset + p]; a[i + offset] = l + r; a[i + offset + p] = (unsigned long long)(mint::mod() + l.val() - r.val()) * irot.val(); } if(s + 1 != (1 << (len - 1))) irot *= info.irate2[__builtin_ctz(~(unsigned int)(s))]; } --len; } else { int p = 1 << (h - len); mint irot = 1, iimag = info.iroot[2]; for(int s = 0; s < (1 << (len - 2)); ++s) { mint irot2 = irot * irot; mint irot3 = irot2 * irot; int offset = s << (h - len + 2); for(int i = 0; i < p; ++i) { auto a0 = 1ULL * a[i + offset + 0 * p].val(); auto a1 = 1ULL * a[i + offset + 1 * p].val(); auto a2 = 1ULL * a[i + offset + 2 * p].val(); auto a3 = 1ULL * a[i + offset + 3 * p].val(); auto a2na3iimag = 1ULL * mint((mint::mod() + a2 - a3) * iimag.val()).val(); a[i + offset] = a0 + a1 + a2 + a3; a[i + offset + 1 * p] = (a0 + (mint::mod() - a1) + a2na3iimag) * irot.val(); a[i + offset + 2 * p] = (a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) * irot2.val(); a[i + offset + 3 * p] = (a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) * irot3.val(); } if(s + 1 != (1 << (len - 2))) irot *= info.irate3[__builtin_ctz(~(unsigned int)(s))]; } len -= 2; } } } template <typename mint> vector<mint> convolution_naive(const vector<mint>& a, const vector<mint>& b) { int n = (int)a.size(), m = (int)b.size(); vector<mint> res(n + m - 1); if(n < m) { for(int j = 0; j < m; ++j) { for(int i = 0; i < n; ++i) { res[i + j] += a[i] * b[j]; } } } else { for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j) { res[i + j] += a[i] * b[j]; } } } return res; } template <typename mint> vector<mint> convolution(vector<mint> a, vector<mint> b) { int n = (int)a.size(), m = (int)b.size(); if(n == 0 or m == 0) return {}; int z = 1; while(z < n + m - 1) z *= 2; assert((mint::mod() - 1) % z == 0); if(min(n, m) <= 60) return convolution_naive(a, b); a.resize(z); b.resize(z); butterfly(a); butterfly(b); for(int i = 0; i < z; ++i) a[i] *= b[i]; butterfly_inv(a); a.resize(n + m - 1); mint iz = mint(z).inv(); for(int i = 0; i < n + m - 1; ++i) a[i] *= iz; return a; } vector<ll> convolution_ll(const vector<ll>& a, const vector<ll>& b) { int n = (int)a.size(), m = (int)b.size(); if(!n or !m) return {}; static constexpr unsigned long long MOD1 = 754974721; static constexpr unsigned long long MOD2 = 167772161; static constexpr unsigned long long MOD3 = 469762049; static constexpr unsigned long long M2M3 = MOD2 * MOD3; static constexpr unsigned long long M1M3 = MOD1 * MOD3; static constexpr unsigned long long M1M2 = MOD1 * MOD2; static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3; static constexpr unsigned long long i1 = 190329765; static constexpr unsigned long long i2 = 58587104; static constexpr unsigned long long i3 = 187290749; static constexpr int MAX_AB_BIT = 24; assert(n + m - 1 <= (1 << MAX_AB_BIT)); using mint1 = StaticModint<MOD1>; using mint2 = StaticModint<MOD2>; using mint3 = StaticModint<MOD3>; vector<mint1> a1(n), b1(m); vector<mint2> a2(n), b2(m); vector<mint3> a3(n), b3(m); for(int i = 0; i < n; ++i) a1[i] = a[i]; for(int i = 0; i < n; ++i) a2[i] = a[i]; for(int i = 0; i < n; ++i) a3[i] = a[i]; for(int i = 0; i < m; ++i) b1[i] = b[i]; for(int i = 0; i < m; ++i) b2[i] = b[i]; for(int i = 0; i < m; ++i) b3[i] = b[i]; vector<mint1> c1 = convolution<mint1>(a1, b1); vector<mint2> c2 = convolution<mint2>(a2, b2); vector<mint3> c3 = convolution<mint3>(a3, b3); vector<ll> c(n + m - 1); for(int i = 0; i < n + m - 1; ++i) { unsigned long long x = 0; x += (c1[i].val() * i1) % MOD1 * M2M3; x += (c2[i].val() * i2) % MOD2 * M1M3; x += (c3[i].val() * i3) % MOD3 * M1M2; ll diff = c1[i].val() - ((ll)x % (ll)MOD1 + (ll)MOD1) % (ll)MOD1; if(diff < 0) diff += MOD1; static constexpr unsigned long long offset[5] = {0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3}; x -= offset[diff % 5]; c[i] = x; } return c; } int main(void) { int n, m, k; cin >> n >> m >> k; string s, t; cin >> s >> t; string u = t + '?' + s; rep(i, 0, n + m + 1) { u[i] = tolower(u[i]); } vector<int> z = z_algorithm(u); vector<ll> a(n), b(m); rep(i, 0, n) { a[i] = 1; if(islower(s[i])) a[i] = -1; } rep(i, 0, m) { b[m - 1 - i] = 1; if(islower(t[i])) b[m - 1 - i] = -1; } vector<ll> c = convolution_ll(a, b); int ans = 0; rep(i, 0, n) { if(z[m + 1 + i] != m) continue; int tmp = c[m - 1 + i]; int cnt = (m - tmp) / 2; if(1 <= cnt and cnt <= k) ans++; } cout << ans << '\n'; }