【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 }

 

posted on 2015-09-23 22:14  Bombe  阅读(260)  评论(0编辑  收藏  举报

导航