結果
| 問題 |
No.2761 Substitute and Search
|
| コンテスト | |
| ユーザー |
norioc
|
| 提出日時 | 2025-05-07 04:47:01 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2,869 ms / 4,000 ms |
| コード長 | 3,398 bytes |
| コンパイル時間 | 5,772 ms |
| コンパイル使用メモリ | 220,116 KB |
| 実行使用メモリ | 135,680 KB |
| 最終ジャッジ日時 | 2025-05-07 04:47:25 |
| 合計ジャッジ時間 | 22,010 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 13 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
const ll B = 1009;
const ll MOD = 998244353;
ll powmod(ll base, ll exp, ll mod) {
ll res = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) res = res * base % mod;
base = base * base % mod;
exp >>= 1;
}
return res;
}
int ceil_pow2(int n) {
int x = 0;
while ((1 << x) < n) x++;
return x;
}
class SegTree {
public:
using S = pll;
using F = function<S(S, S)>;
int n, size, log;
vector<S> d;
F op;
S e;
SegTree(F op_, S e_, const vector<S>& v) : op(op_), e(e_) {
n = v.size();
log = ceil_pow2(n);
size = 1 << log;
d.assign(2 * size, e);
for (int i = 0; i < n; ++i) d[size + i] = v[i];
for (int i = size - 1; i >= 1; --i) update(i);
}
void set(int p, S x) {
assert(0 <= p && p < n);
p += size;
d[p] = x;
for (int i = 1; i <= log; ++i) update(p >> i);
}
S get(int p) const {
assert(0 <= p && p < n);
return d[p + size];
}
S prod(int l, int r) const {
assert(0 <= l && l <= r && r <= n);
S sml = e, smr = e;
l += size;
r += size;
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() const {
return d[1];
}
private:
void update(int k) {
d[k] = op(d[2 * k], d[2 * k + 1]);
}
};
class RollingHashOnSegTree {
public:
SegTree segt;
RollingHashOnSegTree(const string& s) : segt(
[](pll a, pll b) -> pll {
ll h = (a.first * powmod(B, b.second, MOD) + b.first) % MOD;
return {h, a.second + b.second};
},
{0, 0},
[&s]() {
vector<pll> v;
for (char c : s) {
v.emplace_back(c, 1);
}
return v;
}()
) {}
char get(int p) const {
return static_cast<char>(segt.get(p).first);
}
void set(int p, char c) {
segt.set(p, {c, 1});
}
ll prod(int l, int r) const {
return segt.prod(l, r).first;
}
ll all_prod() const {
return segt.all_prod().first;
}
};
ll rh(const string& s) {
ll h = 0;
for (char c : s) {
h = (h * B + c) % MOD;
}
return h;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, L, Q;
cin >> N >> L >> Q;
vector<RollingHashOnSegTree> hs;
for (int i = 0; i < N; ++i) {
string S;
cin >> S;
hs.emplace_back(S);
}
for (int i = 0; i < Q; ++i) {
string t;
cin >> t;
if (t == "1") {
int k;
char c, d;
cin >> k >> c >> d;
--k;
for (auto& h : hs) {
if (h.get(k) == c) {
h.set(k, d);
}
}
} else if (t == "2") {
string s;
cin >> s;
ll th = rh(s);
int res = 0;
for (const auto& h : hs) {
if (h.prod(0, s.size()) == th) {
++res;
}
}
cout << res << '\n';
}
}
return 0;
}
norioc