|
| 1 | +#include <iostream> |
| 2 | +#include <string> |
| 3 | +#include <vector> |
| 4 | + |
| 5 | +using namespace std; |
| 6 | + |
| 7 | +string S, s_begin, s_end; |
| 8 | +const int MAXN = 2005; |
| 9 | +int P1[MAXN][50]; |
| 10 | +int P2[MAXN][50]; |
| 11 | +int sz, step; |
| 12 | +struct node{ |
| 13 | + int nr[2]; |
| 14 | + int p; |
| 15 | +}; |
| 16 | +struct node L[MAXN]; |
| 17 | + |
| 18 | +int my_cmp(struct node &a, struct node &b){ |
| 19 | + return (a.nr[0] == b.nr[0])?(a.nr[1]<b.nr[1]?1:0):(a.nr[0]<b.nr[0]?1:0); |
| 20 | +} |
| 21 | + |
| 22 | +int search(string pattern, string S){ |
| 23 | + int high=sz, mid, low=0, res = -1; |
| 24 | + int p_size = pattern.size(); |
| 25 | + while(low<high){ |
| 26 | + int mid = (high+low)/2; |
| 27 | + string cur = S.substr(L[mid].p, sz); |
| 28 | + if(pattern >= cur){ |
| 29 | + low = mid+1; |
| 30 | + } else if(pattern < cur){ |
| 31 | + high = mid; |
| 32 | + res = mid; |
| 33 | + } |
| 34 | + } |
| 35 | + return res; |
| 36 | +} |
| 37 | + |
| 38 | +int lca(int x, int y, int P[][50]){ |
| 39 | + int k, ret = 0; |
| 40 | + if(x==y)return sz-x; |
| 41 | + for(k=step-1; k>=0 && x<sz && y<sz; k--){ |
| 42 | + if(P[x][k] == P[y][k]){ |
| 43 | + x+= 1<<k, y+= 1<<k, ret += 1<<k; |
| 44 | + } |
| 45 | + } |
| 46 | + return ret; |
| 47 | +} |
| 48 | + |
| 49 | +vector<int> work(int P[][50], string S, string pattern){ |
| 50 | + for(int i=0; i<sz; i++){ |
| 51 | + P[i][0] = S[i] - 'a'; |
| 52 | + L[i].p = i; |
| 53 | + } |
| 54 | + int k, cnt; |
| 55 | + for(cnt=1, k=1; (cnt>>1)<sz; k++, cnt<<=1){ |
| 56 | + for(int i=0; i<sz; i++){ |
| 57 | + L[i].nr[0] = P[i][k-1]; |
| 58 | + L[i].nr[1] = (i+cnt>=sz)?-1:P[i+cnt][k-1]; |
| 59 | + L[i].p = i; |
| 60 | + } |
| 61 | + sort(L, L+sz, my_cmp); |
| 62 | + for(int i=0; i<sz; i++){ |
| 63 | + P[L[i].p][k] = (i>0 && L[i].nr[0] == L[i-1].nr[0] && L[i].nr[1] == L[i-1].nr[1])?P[L[i-1].p][k]:i; |
| 64 | + } |
| 65 | + step = k; |
| 66 | + } |
| 67 | + |
| 68 | + cout<<"building successfully"<<endl; |
| 69 | + for(int i=0; i<sz; i++){ |
| 70 | + cout<<S.substr(L[i].p, sz)<<endl; |
| 71 | + } |
| 72 | + cout<<"rank = "<<endl; |
| 73 | + cout<<"sz = "<<sz<<endl; |
| 74 | + for(int i=0; i<sz; i++){ |
| 75 | + cout<<L[i].p<<" "; |
| 76 | + }cout<<endl; |
| 77 | + |
| 78 | + int up = search(pattern, S); |
| 79 | + cout<<"up = "<<up<<endl; |
| 80 | + vector<int> tmp; |
| 81 | + if(up==-1){ |
| 82 | + return tmp; |
| 83 | + } |
| 84 | + cnt = 0; |
| 85 | + int p_size = pattern.size(); |
| 86 | + for(int i=0; i<p_size; i++){ |
| 87 | + if(pattern[i] == S.substr(L[up].p, sz)[i]){ |
| 88 | + cnt++; |
| 89 | + } |
| 90 | + } |
| 91 | + cout<<"cnt = "<<cnt<<endl; |
| 92 | + if(cnt>=p_size){ |
| 93 | + cout<<"adding "<<L[up].p<<" "<<endl; |
| 94 | + tmp.push_back(L[up].p); |
| 95 | + } |
| 96 | + |
| 97 | + int i, ok = up; |
| 98 | + for(i=up, ok = up; i<sz-1; i++, ok++){ |
| 99 | + cout<<"looking at "<<S.substr(L[i].p, sz)<<" and "<<S.substr(L[i+1].p, sz)<<endl; |
| 100 | + cout<<"lca = "<<lca(L[i].p, L[i+1].p, P)<<endl; |
| 101 | + if(lca(L[i].p, L[i+1].p, P) < p_size){ |
| 102 | + break; |
| 103 | + } |
| 104 | + cout<<"now ok = "<<ok<<endl; |
| 105 | + } |
| 106 | + cout<<"up = "<<up<<" ok = "<<ok<<endl; |
| 107 | + for(int i=up; i<ok; i++){ |
| 108 | + cout<<"pushing "<<L[i+1].p<<endl; |
| 109 | + tmp.push_back(L[i+1].p); |
| 110 | + } |
| 111 | + |
| 112 | + |
| 113 | + cout<<"ok tmp = "<<endl; |
| 114 | + for(int i=0; i<tmp.size(); i++){ |
| 115 | + cout<<tmp[i]<<" "; |
| 116 | + }cout<<endl; |
| 117 | + return tmp; |
| 118 | +} |
| 119 | + |
| 120 | + |
| 121 | +int main(){ |
| 122 | + cin>>S; |
| 123 | + cin>>s_begin; |
| 124 | + cin>>s_end; |
| 125 | + |
| 126 | + sz = S.size(); |
| 127 | + vector<int> pre = work(P1, S, s_begin); |
| 128 | + vector<int> suf = work(P2, string(S.rbegin(), S.rend()), string(s_end.rbegin(), s_end.rend())); |
| 129 | + |
| 130 | + |
| 131 | + cout<<"ok suf = "<<endl; |
| 132 | + for(int i=0; i<suf.size(); i++){ |
| 133 | + cout<<"original = "<<suf[i]<<endl; |
| 134 | + suf[i] += s_end.size()-1; |
| 135 | + suf[i] = sz - suf[i] - 1; |
| 136 | + } |
| 137 | + int front=0, rear = suf.size()-1; |
| 138 | + |
| 139 | + for(int i=0; i<pre.size(); i++){ |
| 140 | + cout<<"pre "<<i<<" = "<<pre[i]<<endl; |
| 141 | + } |
| 142 | + |
| 143 | + for(int i=0; i<suf.size(); i++){ |
| 144 | + cout<<"suf "<<i<<" = "<<suf[i]<<endl; |
| 145 | + } |
| 146 | + |
| 147 | + sort(pre.begin(), pre.end()); |
| 148 | + sort(suf.begin(), suf.end()); |
| 149 | + |
| 150 | + int ans =0; |
| 151 | + // all staring and ending points |
| 152 | + for(int i=0; i<pre.size(); i++){ |
| 153 | + for(int j=0; j<suf.size(); j++){ |
| 154 | + if(pre[i]<=suf[j]){ |
| 155 | + ans += 1; |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + cout<<ans<<endl; |
| 160 | + |
| 161 | + return 0; |
| 162 | +} |
| 163 | + |
0 commit comments