pub use __cargo_equip::prelude::*; use acl_segtree::*; use proconio::{ input, marker::{Chars, Usize1}, }; const MOD: u64 = (1 << 61) - 1; const BASE: u64 = 0x1234567; const fn mul(a: u64, b: u64) -> u64 { let (au, ad) = (a >> 31, a & (1 << 31) - 1); let (bu, bd) = (b >> 31, b & (1 << 31) - 1); let mid = ad * bu * au * bd; let (midu, midd) = (mid >> 30, mid & (1 << 30) - 1); modulo(au * bu * 2 + midu + (midd << 31) + ad * bd) } const fn modulo(x: u64) -> u64 { let mut res = (x >> 61) + (x & (1 << 61) - 1); if res >= MOD { res -= MOD; } res } const POW: [u64; 3000] = { let mut pow = [0; 3000]; pow[0] = 1; let mut i = 1; while i < 3000 { pow[i] = mul(pow[i - 1], BASE); i += 1; } pow }; fn main() { input! { N: usize, L: usize, Q: usize, mut S: [Chars; N], } struct M; impl Monoid for M { type S = u64; fn binary_operation(&x1: &Self::S, &x2: &Self::S) -> Self::S { modulo(x1 + x2) } fn identity() -> Self::S { 0 } } let mut hashes = S .iter() .map(|s| { Segtree::::from( (0..L) .map(|k| mul(POW[k], (s[k] as u8 - b'a' + 1) as u64)) .collect::>(), ) }) .collect::>(); eprintln!("{:?}", hashes[0].all_prod()); for _ in 0..Q { input!(qtype: usize); if qtype == 1 { input!(k: Usize1, c: char, d: char); for i in 0..N { if S[i][k] == c { S[i][k] = d; hashes[i].set(k, mul(POW[k], (d as u8 - b'a') as u64 + 1)); } } } else { input!(t: Chars); let hash = (0..t.len()) .map(|k| mul(POW[k], (t[k] as u8 - b'a' + 1) as u64)) .fold(0, |x, y| modulo(x + y)); let mut ans = 0; for i in 0..N { if hashes[i].prod(0, t.len()) == hash { ans += 1; } } println!("{ans}"); } } } // The following code was expanded by `cargo-equip`. /// # Bundled libraries /// /// - `ac-library-rs-parted-internal-bit 0.1.0 (path+███████████████████████████████████████████████████████████████████████████████)` published in https://github.com/qryxip/ac-library-rs-parted licensed under `CC0-1.0` as `crate::__cargo_equip::crates::__ac_library_rs_parted_internal_bit_0_1_0` /// - `ac-library-rs-parted-internal-type-traits 0.1.0 (path+███████████████████████████████████████████████████████████████████████████████████████)` published in https://github.com/qryxip/ac-library-rs-parted licensed under `CC0-1.0` as `crate::__cargo_equip::crates::__ac_library_rs_parted_internal_type_traits_0_1_0` /// - `ac-library-rs-parted-segtree 0.1.0 (path+██████████████████████████████████████████████████████████████████████████)` published in https://github.com/qryxip/ac-library-rs-parted licensed under `CC0-1.0` as `crate::__cargo_equip::crates::acl_segtree` #[cfg_attr(any(), rustfmt::skip)] #[allow(unused)] mod __cargo_equip { pub(crate) mod crates { pub mod __ac_library_rs_parted_internal_bit_0_1_0 {pub use self::internal_bit::*;mod internal_bit{#[allow(dead_code)]pub fn ceil_pow2(n:u32)->u32{32-n.saturating_sub(1).leading_zeros()}}} pub mod __ac_library_rs_parted_internal_type_traits_0_1_0 {pub use self::internal_type_traits::*;mod internal_type_traits{use std::{fmt,iter::{Product,Sum},ops::{Add,AddAssign,BitAnd,BitAndAssign,BitOr,BitOrAssign,BitXor,BitXorAssign,Div,DivAssign,Mul,MulAssign,Not,Rem,RemAssign,Shl,ShlAssign,Shr,ShrAssign,Sub,SubAssign,},};#[doc=" Corresponds to `std::is_integral` in C++."]pub trait Integral:'static+Send+Sync+Copy+Ord+Not+Add+Sub+Mul+Div+Rem+AddAssign+SubAssign+MulAssign+DivAssign+RemAssign+Sum+Product+BitOr+BitAnd+BitXor+BitOrAssign+BitAndAssign+BitXorAssign+Shl+Shr+ShlAssign+ShrAssign+fmt::Display+fmt::Debug+fmt::Binary+fmt::Octal+Zero+One+BoundedBelow+BoundedAbove{}#[doc=" Class that has additive identity element"]pub trait Zero{#[doc=" The additive identity element"]fn zero()->Self;}#[doc=" Class that has multiplicative identity element"]pub trait One{#[doc=" The multiplicative identity element"]fn one()->Self;}pub trait BoundedBelow{fn min_value()->Self;}pub trait BoundedAbove{fn max_value()->Self;}macro_rules!impl_integral{($($ty:ty),*)=>{$(impl Zero for$ty{#[inline]fn zero()->Self{0}}impl One for$ty{#[inline]fn one()->Self{1}}impl BoundedBelow for$ty{#[inline]fn min_value()->Self{Self::min_value()}}impl BoundedAbove for$ty{#[inline]fn max_value()->Self{Self::max_value()}}impl Integral for$ty{})*};}impl_integral!(i8,i16,i32,i64,i128,isize,u8,u16,u32,u64,u128,usize);}} pub mod acl_segtree {use crate::__cargo_equip::preludes::acl_segtree::*;use crate::__cargo_equip::crates::__ac_library_rs_parted_internal_bit_0_1_0 as internal_bit;use crate::__cargo_equip::crates::__ac_library_rs_parted_internal_type_traits_0_1_0 as internal_type_traits;pub use self::segtree::*;mod segtree{use crate::__cargo_equip::preludes::acl_segtree::*;use super::internal_bit::ceil_pow2;use super::internal_type_traits::{BoundedAbove,BoundedBelow,One,Zero};use std::cmp::{max,min};use std::convert::Infallible;use std::marker::PhantomData;use std::ops::{Add,Mul};pub trait Monoid{type S:Clone;fn identity()->Self::S;fn binary_operation(a:&Self::S,b:&Self::S)->Self::S;}pub struct Max(Infallible,PhantomDataS>);implMonoid for Maxwhere S:Copy+Ord+BoundedBelow,{type S=S;fn identity()->Self::S{S::min_value()}fn binary_operation(a:&Self::S,b:&Self::S)->Self::S{max(*a,*b)}}pub struct Min(Infallible,PhantomDataS>);implMonoid for Minwhere S:Copy+Ord+BoundedAbove,{type S=S;fn identity()->Self::S{S::max_value()}fn binary_operation(a:&Self::S,b:&Self::S)->Self::S{min(*a,*b)}}pub struct Additive(Infallible,PhantomDataS>);implMonoid for Additivewhere S:Copy+Add+Zero,{type S=S;fn identity()->Self::S{S::zero()}fn binary_operation(a:&Self::S,b:&Self::S)->Self::S{*a+*b}}pub struct Multiplicative(Infallible,PhantomDataS>);implMonoid for Multiplicativewhere S:Copy+Mul+One,{type S=S;fn identity()->Self::S{S::one()}fn binary_operation(a:&Self::S,b:&Self::S)->Self::S{*a**b}}implDefault for Segtree{fn default()->Self{Segtree::new(0)}}implSegtree{pub fn new(n:usize)->Segtree{vec![M::identity();n].into()}}implFrom>for Segtree{fn from(v:Vec)->Self{let n=v.len();let log=ceil_pow2(n as u32)as usize;let size=1<Segtree{pub fn set(&mut self,mut p:usize,x:M::S){assert!(p>i);}}pub fn get(&self,p:usize)->M::S{assert!(pM::S{assert!(l<=r&&r<=self.n);let mut sml=M::identity();let mut smr=M::identity();l+=self.size;r+=self.size;while l>=1;r>>=1;}M::binary_operation(&sml,&smr)}pub fn all_prod(&self)->M::S{self.d[1].clone()}pub fn max_right(&self,mut l:usize,f:F)->usize where F:Fn(&M::S)->bool,{assert!(l<=self.n);assert!(f(&M::identity()));if l==self.n{return self.n;}l+=self.size;let mut sm=M::identity();while{while l%2==0{l>>=1;}if!f(&M::binary_operation(&sm,&self.d[l])){while l(&self,mut r:usize,f:F)->usize where F:Fn(&M::S)->bool,{assert!(r<=self.n);assert!(f(&M::identity()));if r==0{return 0;}r+=self.size;let mut sm=M::identity();while{r-=1;while r>1&&r%2==1{r>>=1;}if!f(&M::binary_operation(&self.d[r],&sm)){while rwhere M:Monoid,{n:usize,size:usize,log:usize,d:Vec,}}} } pub(crate) mod macros { pub mod __ac_library_rs_parted_internal_bit_0_1_0 {} pub mod __ac_library_rs_parted_internal_type_traits_0_1_0 {} pub mod acl_segtree {} } pub(crate) mod prelude {pub use crate::__cargo_equip::crates::*;} mod preludes { pub mod __ac_library_rs_parted_internal_bit_0_1_0 {} pub mod __ac_library_rs_parted_internal_type_traits_0_1_0 {} pub mod acl_segtree {pub(in crate::__cargo_equip)use crate::__cargo_equip::crates::{__ac_library_rs_parted_internal_bit_0_1_0 as __acl_internal_bit,__ac_library_rs_parted_internal_type_traits_0_1_0 as __acl_internal_type_traits};} } }