結果
| 問題 |
No.2761 Substitute and Search
|
| コンテスト | |
| ユーザー |
norioc
|
| 提出日時 | 2025-05-07 04:44:19 |
| 言語 | Java (openjdk 23) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,299 bytes |
| コンパイル時間 | 6,501 ms |
| コンパイル使用メモリ | 83,124 KB |
| 実行使用メモリ | 331,656 KB |
| 最終ジャッジ日時 | 2025-05-07 04:44:38 |
| 合計ジャッジ時間 | 14,786 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 1 TLE * 2 -- * 10 |
ソースコード
import java.util.*;
import java.io.*;
public class Main {
static int _ceilPow2(int n) {
int x = 0;
while ((1 << x) < n) x++;
return x;
}
interface Op<T> {
T apply(T a, T b);
}
static class SegTree<T> {
private final Op<T> op;
private final T e;
private final int n, log, size;
private final Object[] d;
public SegTree(Op<T> op, T e, List<T> v) {
this.op = op;
this.e = e;
this.n = v.size();
this.log = _ceilPow2(n);
this.size = 1 << log;
this.d = new Object[2 * size];
Arrays.fill(d, e);
for (int i = 0; i < n; i++) {
d[size + i] = v.get(i);
}
for (int i = size - 1; i > 0; i--) {
update(i);
}
}
public void set(int p, T x) {
if (p < 0 || p >= n) throw new AssertionError();
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) {
update(p >> i);
}
}
@SuppressWarnings("unchecked")
public T get(int p) {
if (p < 0 || p >= n) throw new AssertionError();
return (T) d[p + size];
}
@SuppressWarnings("unchecked")
public T prod(int l, int r) {
if (l < 0 || l > r || r > n) throw new AssertionError();
T sml = e;
T smr = e;
l += size;
r += size;
while (l < r) {
if ((l & 1) == 1) sml = op.apply(sml, (T) d[l++]);
if ((r & 1) == 1) smr = op.apply((T) d[--r], smr);
l >>= 1;
r >>= 1;
}
return op.apply(sml, smr);
}
@SuppressWarnings("unchecked")
public T allProd() {
return (T) d[1];
}
private void update(int k) {
d[k] = op.apply((T) d[2 * k], (T) d[2 * k + 1]);
}
}
static class RollingHashOnSegTree {
final int B = 1009;
final int MOD = 998244353;
SegTree<long[]> segt;
public RollingHashOnSegTree(String s) {
Op<long[]> op = (a, b) -> {
long h = (a[0] * powMod(B, b[1], MOD) + b[0]) % MOD;
return new long[]{h, a[1] + b[1]};
};
List<long[]> v = new ArrayList<>();
for (char c : s.toCharArray()) {
v.add(new long[]{c, 1});
}
this.segt = new SegTree<>(op, new long[]{0, 0}, v);
}
public char get(int p) {
return (char) segt.get(p)[0];
}
public void set(int p, char c) {
segt.set(p, new long[]{c, 1});
}
public long prod(int l, int r) {
return segt.prod(l, r)[0];
}
public long allProd() {
return segt.allProd()[0];
}
}
static long rh(String s) {
final int B = 1009;
final int MOD = 998244353;
long h = 0;
for (char c : s.toCharArray()) {
h = (h * B + c) % MOD;
}
return h;
}
static long powMod(long base, long exp, long mod) {
long result = 1;
base %= mod;
while (exp > 0) {
if ((exp & 1) == 1) result = result * base % mod;
base = base * base % mod;
exp >>= 1;
}
return result;
}
public static void main(String[] args) throws IOException {
FastReader in = new FastReader();
int N = in.nextInt();
int L = in.nextInt();
int Q = in.nextInt();
List<RollingHashOnSegTree> hs = new ArrayList<>();
for (int i = 0; i < N; i++) {
String S = in.next();
hs.add(new RollingHashOnSegTree(S));
}
for (int i = 0; i < Q; i++) {
String[] qs = in.nextLine().split(" ");
if (qs[0].equals("1")) {
int k = Integer.parseInt(qs[1]) - 1;
char c = qs[2].charAt(0);
char d = qs[3].charAt(0);
for (RollingHashOnSegTree h : hs) {
if (h.get(k) == c) {
h.set(k, d);
}
}
} else if (qs[0].equals("2")) {
String t = qs[1];
long th = rh(t);
int res = 0;
for (RollingHashOnSegTree h : hs) {
if (h.prod(0, t.length()) == th) {
res++;
}
}
System.out.println(res);
}
}
}
// 高速入力
static class FastReader {
BufferedReader br;
StringTokenizer st;
FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() throws IOException {
while (st == null || !st.hasMoreTokens())
st = new StringTokenizer(br.readLine());
return st.nextToken();
}
String nextLine() throws IOException {
return br.readLine();
}
int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
}
norioc