听说单hash能过23333
于是乎hash乱搞一下就好了辣 然而map要TLE ....
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<map>
#define SF scanf
#define PF printf
#define idx(c) ((c)-'a'+1)
using namespace std;
typedef unsigned int LL;
typedef unsigned int uint;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
const int MAXN = 4000000;
const int bas = 28;
const int MAXNODE = 4999997;
string A[MAXN+10], B[MAXN+10];
int n, m, len1, len2;
uint base[MAXN+10], Hash[MAXN+10];
int M[MAXNODE+10];
LL sta[MAXNODE+10];
long long ans = 0;
char ch[MAXN+10];
uint hash(int l, int r) {
if(l > r) return 0;
return Hash[r]-Hash[l-1] * base[r-l+1];
}
int trans(LL x) {
int i = x % MAXNODE;
for( ; sta[i] != x && ~sta[i]; ) i = (i == MAXNODE) ? 0 : i+1;
sta[i] = x;
return i;
}
int main() {
memset(sta, -1, sizeof(sta));
n = read(); m = read(); len1 = read(); len2 = read();
base[0] = 1;
for(int i = 1; i <= len1+len2; i++) base[i] = base[i-1] * bas;
int mid = len1+len2>>1;
string *s = A, *t = B;
for(int i = 1; i <= n; i++) SF("%s", ch), s[i] = string(ch);
for(int i = 1; i <= m; i++) SF("%s", ch), t[i] = string(ch);
if(len1 < len2) {
swap(s, t);
swap(n, m); swap(len1, len2);
}
for(int i = 1; i <= m; i++) {
LL h = 0;
for(int j = 0; j < len2; j++)
h = h * bas + idx(t[i][j]);
M[trans(h)]++;
}
for(int i = 1; i <= n; i++) {
for(int j = 0; j < mid*2; j++) Hash[j+1] = Hash[j] * bas + idx(s[i][j%mid]);
LL x = 0;
for(int j = mid; j < len1; j++)
x = x * bas + idx(s[i][j]);
for(int j = 1; j <= mid; j++) {
if(hash(j, j+len1-mid-1) == x) {
LL t = hash(j+len1-mid, j+mid-1);
ans += M[trans(t)];
}
}
}
PF("%lld\n", ans);
}