結果
| 問題 |
No.2626 Similar But Different Name
|
| コンテスト | |
| ユーザー |
SnowBeenDiding
|
| 提出日時 | 2024-02-09 23:23:26 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,146 bytes |
| コンパイル時間 | 4,932 ms |
| コンパイル使用メモリ | 315,300 KB |
| 実行使用メモリ | 98,524 KB |
| 最終ジャッジ日時 | 2024-09-28 16:33:36 |
| 合計ジャッジ時間 | 10,344 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 15 TLE * 1 -- * 19 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
#define rep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
using namespace std;
using namespace atcoder;
typedef long long ll;
struct RollingHash {
int n;
static const ll base1 = 1009;
static const ll base2 = 2009;
static const ll mod1 = 1000000007;
static const ll mod2 = 1000000009;
vector<ll> hash1, hash2, pow1, pow2;
RollingHash() {}
RollingHash(const string &S) {
n = (int)S.size();
hash1.assign(n + 1, 0);
hash2.assign(n + 1, 0);
pow1.assign(n + 1, 1);
pow2.assign(n + 1, 1);
for (int i = 0; i < n; ++i) {
hash1[i + 1] = (hash1[i] * base1 + S[i]) % mod1;
hash2[i + 1] = (hash2[i] * base2 + S[i]) % mod2;
pow1[i + 1] = (pow1[i] * base1) % mod1;
pow2[i + 1] = (pow2[i] * base2) % mod2;
}
}
/**
* S の [l, r) のハッシュ値を返す
* O(1)
*/
inline pair<ll, ll> get(int l, int r) const {
ll res1 = hash1[r] - hash1[l] * pow1[r - l] % mod1;
if (res1 < 0) res1 += mod1;
ll res2 = hash2[r] - hash2[l] * pow2[r - l] % mod2;
if (res2 < 0) res2 += mod2;
return make_pair(res1, res2);
}
/**
* S のハッシュ値を返す
* O(1)
*/
inline pair<ll, ll> hash() const { return get(0, (int)hash1.size() - 1); }
/**
* LCP (Longest Common Prefix)
* O( log N )
*/
inline int getLCP(int a, int b) const {
int len = min((int)hash1.size() - a, (int)hash1.size() - b);
int low = 0, high = len;
while (high - low > 1) {
int mid = (low + high) >> 1;
if (get(a, a + mid) != get(b, b + mid))
high = mid;
else
low = mid;
}
return low;
}
/**
* hash h1 と 長さ h2_len の文字列の hash h2 を結合
*/
pair<ll, ll> concat(pair<ll, ll> h1, pair<ll, ll> h2, ll h2_len) {
return make_pair((h1.first * pow1[h2_len] + h2.first) % mod1,
(h1.second * pow2[h2_len] + h2.second) % mod2);
}
/**
* 文字列の最小周期を返す
*/
int max_repeat(bool multiple_only = false) {
for (int i = 1; i < n; i++) {
if (multiple_only && n % i != 0) continue;
if (n - i < i) break;
if (get(0, n - i) == get(i, n)) {
return i;
}
}
return n;
}
/**
* hash h を count 回結合 (WIP)
*/
pair<ll, ll> times(pair<ll, ll> h, ll len, ll count) {
pair<ll, ll> ret = {0, 0}, now = h;
ll pw = 1;
while (count) {
if (count & 1) ret = concat(ret, now, len * pw);
now = concat(now, now, len * pw);
count >>= 1;
pw <<= 1;
}
return ret;
}
};
template <typename T>
vector<T> convolution_rev(vector<T> a, vector<T> b) {
int n = a.size();
int m = b.size();
reverse(b.begin(), b.end());
auto v = convolution_ll(a, b);
vector<T> ret(n - m + 1);
rep(i, 0, n - m + 1) ret[i] = v[i + m - 1];
return ret;
}
int main() {
int n, m, k;
string s, t;
cin >> n >> m >> k >> s >> t;
string sb = s, tb = t;
rep(i, 0, sb.size()) sb[i] = toupper(sb[i]);
rep(i, 0, tb.size()) tb[i] = toupper(tb[i]);
RollingHash rsb(sb), rtb(tb);
vector<int> cnt(n - m + 1, 0);
vector<ll> a(n), b(m);
rep(i, 0, 52) {
char c = (i < 26 ? 'a' + i : 'A' + i - 26);
char C = (i < 26 ? 'A' + i : 'a' + i - 26);
rep(j, 0, n) {
if (s[j] == c)
a[j] = 1;
else
a[j] = 0;
}
rep(i, 0, m) {
if (t[i] == C)
b[i] = 1;
else
b[i] = 0;
}
auto v = convolution_rev(a, b);
rep(j, 0, n - m + 1) cnt[j] += v[j];
}
int ans = 0;
rep(i, 0, n - m + 1) {
if (rsb.get(i, i + m) == rtb.get(0, m) && cnt[i] > 0 && cnt[i] <= k) {
ans++;
}
}
cout << ans << endl;
}
SnowBeenDiding