結果
問題 |
No.2761 Substitute and Search
|
ユーザー |
![]() |
提出日時 | 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; }