#include using namespace std; long long mod = 998244353; //入力が必ずmod未満の時に使う. struct mint{ long long v = 0; mint(){} mint(int a){v = a;} mint(long long a){v = a;} mint(unsigned long long a){v = a;} long long val(){return v;} void modu(){v %= mod;} mint repeat2mint(long long a,long long b){ mint ret = 1,p = a; int Log = 60; if(b <= 2e9) Log = 30; for(int i=0; i(mint b){if(v > b.v) return true; else return false;} bool operator>=(mint b){if(v >= b.v) return true; else return false;} bool operator<(mint b){if(v < b.v) return true; else return false;} bool operator<=(mint b){if(v <= b.v) return true; else return false;} mint pow(long long x){return repeat2mint(v,x);} mint inv(){return mint(1)/v;} }; namespace to_fold{ //纏めて折り畳むためのやつ 苦労したが結局ほぼACLの写経. int countzero(unsigned long long x){ if(x == 0) return 64; else return __popcount((x&-x)-1); } pair invgcd(long long a,long long b){ a = (a+b)%b; if(a == 0) return {b,0}; long long x = 0,y = 1,memo = b; while(a){ x -= y*(b/a); b %= a; swap(a,b); swap(x,y); } x = (x+memo/b)%(memo/b); return {b,x}; } struct fftinfo{ vector root,iroot,rate2,irate2,rate3,irate3; fftinfo(mint g){ int rank2 = countzero(mod-1); root.resize(rank2+1),iroot = root; rate2.resize(max(0,rank2-2+1)); irate2 = rate2; rate3.resize(max(0,rank2-3+1)); irate3 = rate3; root.at(rank2) = g.pow((mod-1)>>rank2); iroot.at(rank2) = root.at(rank2).inv(); for(int i=rank2-1; i>=0; i--){ root.at(i) = root.at(i+1)*root.at(i+1); iroot.at(i) = iroot.at(i+1)*iroot.at(i+1); } mint mul = 1,imul = 1; for(int i=0; i<=rank2-2; i++){ rate2.at(i) = root.at(i+2)*mul; irate2.at(i) = iroot.at(i+2)*imul; mul *= iroot.at(i+2),imul *= root.at(i+2); } mul = 1,imul = 1; for(int i=0; i<=rank2-3; i++){ rate3.at(i) = root.at(i+3)*mul; irate3.at(i) = iroot.at(i+3)*imul; mul *= iroot.at(i+3),imul *= root.at(i+3); } } }; mint findroot(){ if(mod == 998244353) return mint(3); else if(mod == 754974721) return mint(11); else if(mod == 167772161) return mint(3); else if(mod == 469762049) return mint(3); long long p = mod-1; vector P; for(long long i=2; i*i<=p; i++){ if(p%i) continue; while(p%i == 0) p /= i; P.push_back(i); } if(p != 1) P.push_back(p); p = mod-1; random_device rnd; mt19937 mt(rnd()); while(true){ mint ret = mt()%mod; if(ret == 1 || ret == 0) continue; if(ret.pow(p) != 1) continue; bool ok = true; for(auto check : P) if(ret.pow(p/check) == 1){ok = false; break;} if(ok) return ret; } //O(√P)らしいです. } void NTT(vector &A,fftinfo &info){ int N = A.size(),ln = countzero(N); int dep = 0; while(dep < ln){ if(ln-dep == 1){ int p = 1<<(ln-dep-1); mint rot = 1; for(int o=0; o<(1< &A,fftinfo &info){ int N = A.size(),ln = countzero(N); int dep = ln; while(dep){ if(dep == 1){ int p = 1<<(ln-dep); mint irot = 1; for(int o=0; o<(1<<(dep-1)); o++){ int offset = o<<(ln-dep+1); for(int i=0; i convolution(vector &A,vector &B){ int siza = A.size(),sizb = B.size(),sizc = siza+sizb-1,N = 1; if(siza == 0 || sizb == 0) return {}; while(N <= sizc) N *= 2; vector ca = A,cb = B; ca.resize(N),cb.resize(N); assert((mod-1)%N == 0); mint root = findroot(); fftinfo info(root); NTT(ca,info); NTT(cb,info); for(int i=0; i convolution_ll(vector &A,vector &B){ int siza = A.size(),sizb = B.size(),sizc = siza+sizb-1; if(siza == 0 || sizb == 0) return {}; unsigned long long mod1 = 754974721,mod2 = 167772161,mod3 = 469762049; unsigned long long m1m2 = mod1*mod2,m2m3 = mod2*mod3,m3m1 = mod3*mod1,m1m2m3 = mod1*mod2*mod3; unsigned long long i1 = invgcd(m2m3,mod1).second,i2 = invgcd(m3m1,mod2).second,i3 = invgcd(m1m2,mod3).second; assert(sizc <= (1<<24)); mod = mod1; vector a(siza),b(sizb); for(int i=0; i C1 = convolution(a,b); mod = mod2; for(int i=0; i C2 = convolution(a,b); mod = mod3; for(int i=0; i C3 = convolution(a,b); vector ret(sizc); vector offset = {0,0,m1m2m3,2*m1m2m3,3*m1m2m3}; for(int i=0; i Zalgo(string s){ int l1 = 0,N = s.size(); vector ret(N); for(int i=1; i> N >> M >> K; string s,t; cin >> s >> t; string st = ""; for(auto c : t){ if(isupper(c)) c -= 'A'-'a'; st += c; } st += "&"; for(auto c : s){ if(isupper(c)) c -= 'A'-'a'; st += c; } vector Z = Zalgo(st); reverse(t.begin(),t.end()); vector A1(N),B1(M),A2(N),B2(M); for(int i=0; i C1= convolution(A1,B1); vector C2 = convolution(A2,B2); int answer = 0; for(int i=M-1; i