误以为是求满足条件的substring总数(解法是KMP分别以Sbeg和Send作为模式串求解满足条件的position,然后O(n^2)或者O(nlgn)求解)。
后来发现是求set(all valid substring), O(n^2)遍历起始和终止位置并利用set肯定超时。因此,利用字符串hash求解。
/* 113B */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int prime = ;
const int maxn = ;
char s[maxn];
char s1[maxn];
char s2[maxn];
int nxt1[maxn];
int nxt2[maxn];
bool valid1[maxn];
bool valid2[maxn];
__int64 Pow[maxn];
__int64 hash[maxn]; void getNext(char *s, int nxt[]) {
int slen = strlen(s);
int i = , j = -; nxt[] = -;
while (i < slen) {
if (j==- || s[i]==s[j]) {
++i;
++j;
nxt[i] = j;
} else {
j = nxt[j];
}
}
} void kmp(char *s, char *d, int nxt[], bool valid[]) {
int slen = strlen(s);
int dlen = strlen(d);
int i = , j = ; while (i < dlen) {
if (d[i] == s[j]) {
++i;
++j;
} else {
j = nxt[j];
if (j == -) {
j = ;
++i;
}
}
if (j == slen) {
valid[i-slen] = true;
j = nxt[j];
}
}
} void init() {
Pow[] = ;
rep(i, , maxn)
Pow[i] = Pow[i-] * prime; int slen = strlen(s);
hash[] = s[] - 'a' + ;
rep(i, , slen)
hash[i] = hash[i-] * prime + s[i]-'a'+;
} __int64 getHash(int b, int e) {
return hash[e] - (b== ? 0LL : hash[b-]) * Pow[e-b+];
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif scanf("%s %s %s", s, s1, s2); init();
getNext(s1, nxt1);
getNext(s2, nxt2); int i, j, k;
int slen = strlen(s);
int slen1 = strlen(s1);
int slen2 = strlen(s2); kmp(s1, s, nxt1, valid1);
kmp(s2, s, nxt2, valid2); vector<__int64> vc; for (i=; i<slen; ++i) {
if (!valid1[i])
continue;
for (j=i; j<slen; ++j) {
if (valid2[j] && i+slen1<=j+slen2) {
vc.pb(getHash(i, j+slen2-));
}
}
} sort(all(vc));
int sz = SZ(vc);
int ans = ; for (i=sz-; i>=; --i) {
if (i== || vc[i]!=vc[i-])
++ans;
}
printf("%d\n", ans); #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}