【CF】86 B. Petr#
误以为是求满足条件的substring总数(解法是KMP分别以Sbeg和Send作为模式串求解满足条件的position,然后O(n^2)或者O(nlgn)求解)。
后来发现是求set(all valid substring), O(n^2)遍历起始和终止位置并利用set肯定超时。因此,利用字符串hash求解。
1 /* 113B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int prime = 17239; 43 const int maxn = 2005; 44 char s[maxn]; 45 char s1[maxn]; 46 char s2[maxn]; 47 int nxt1[maxn]; 48 int nxt2[maxn]; 49 bool valid1[maxn]; 50 bool valid2[maxn]; 51 __int64 Pow[maxn]; 52 __int64 hash[maxn]; 53 54 void getNext(char *s, int nxt[]) { 55 int slen = strlen(s); 56 int i = 0, j = -1; 57 58 nxt[0] = -1; 59 while (i < slen) { 60 if (j==-1 || s[i]==s[j]) { 61 ++i; 62 ++j; 63 nxt[i] = j; 64 } else { 65 j = nxt[j]; 66 } 67 } 68 } 69 70 void kmp(char *s, char *d, int nxt[], bool valid[]) { 71 int slen = strlen(s); 72 int dlen = strlen(d); 73 int i = 0, j = 0; 74 75 while (i < dlen) { 76 if (d[i] == s[j]) { 77 ++i; 78 ++j; 79 } else { 80 j = nxt[j]; 81 if (j == -1) { 82 j = 0; 83 ++i; 84 } 85 } 86 if (j == slen) { 87 valid[i-slen] = true; 88 j = nxt[j]; 89 } 90 } 91 } 92 93 void init() { 94 Pow[0] = 1; 95 rep(i, 1, maxn) 96 Pow[i] = Pow[i-1] * prime; 97 98 int slen = strlen(s); 99 hash[0] = s[0] - 'a' + 1; 100 rep(i, 1, slen) 101 hash[i] = hash[i-1] * prime + s[i]-'a'+1; 102 } 103 104 __int64 getHash(int b, int e) { 105 return hash[e] - (b==0 ? 0LL : hash[b-1]) * Pow[e-b+1]; 106 } 107 108 int main() { 109 ios::sync_with_stdio(false); 110 #ifndef ONLINE_JUDGE 111 freopen("data.in", "r", stdin); 112 freopen("data.out", "w", stdout); 113 #endif 114 115 scanf("%s %s %s", s, s1, s2); 116 117 init(); 118 getNext(s1, nxt1); 119 getNext(s2, nxt2); 120 121 122 int i, j, k; 123 int slen = strlen(s); 124 int slen1 = strlen(s1); 125 int slen2 = strlen(s2); 126 127 kmp(s1, s, nxt1, valid1); 128 kmp(s2, s, nxt2, valid2); 129 130 vector<__int64> vc; 131 132 for (i=0; i<slen; ++i) { 133 if (!valid1[i]) 134 continue; 135 for (j=i; j<slen; ++j) { 136 if (valid2[j] && i+slen1<=j+slen2) { 137 vc.pb(getHash(i, j+slen2-1)); 138 } 139 } 140 } 141 142 sort(all(vc)); 143 int sz = SZ(vc); 144 int ans = 0; 145 146 for (i=sz-1; i>=0; --i) { 147 if (i==0 || vc[i]!=vc[i-1]) 148 ++ans; 149 } 150 printf("%d\n", ans); 151 152 #ifndef ONLINE_JUDGE 153 printf("time = %d.\n", (int)clock()); 154 #endif 155 156 return 0; 157 }