#include #include #include #include using namespace std; /* Mamber & Myers Suffix array */ typedef pair pp; struct less_{ vector &last; int step; less_(vector &last, int step):last(last), step(step){} bool operator () (int lhs, int rhs) const{ return(pp(last[lhs], lhs+step < last.size() ? last[lhs+step] : -1) < pp(last[rhs], rhs+step < last.size() ? last[rhs+step] : -1)); } }; vector suffix_array(string &str) { int N = str.size(); vector last(str.begin(), str.end()); // what to do with 0xff or sth ? vector ix(N), next(N); for(int i = 0; i < N; ++i) ix[i] = i; for(int k = 1; ; k *= 2){ sort(ix.begin(), ix.end(), less_(last, k)); int alphas = 0; next[ix[0]] = 0; for(int i = 1; i < N; ++i){ if(less_(last, k)(ix[i-1], ix[i])) ++alphas; next[ix[i]] = alphas; } if(alphas >= N-1) break; next.swap(last); } vector ret; for(int i = 0; i < ix.size(); ++i) ret.push_back(str.c_str() + ix[i]); return ret; } bool cmp(const char *l, const char *r) { return strcmp(l, r) < 0; } /* template T bound(bool islower, string& text, string key, T beg, T en) { if(beg == en) return beg; T middle = beg + (en - beg) / 2; // cout <<"Middle = " << *middle << endl; string t(text, *middle, key.size()); if((islower && t < key) || (!islower && t <= key)) return bound(islower, text, key, middle + 1, en); else return bound(islower, text, key, beg, middle); }*/ int main(void) { ifstream cin("english.in"); int ncases = 0; while(true){ string line; if(!getline(cin, line)) break; if(ncases) cout << endl; ++ncases; string thetext; while(getline(cin, line)){ if(line == "%%%%%") break; thetext += ' '; thetext += line; } vector sa = suffix_array(thetext); cout << "Case " << ncases << ":" << endl; while(getline(cin, line)){ if(line == "%%%%%") break; string linenxt = line; ++linenxt[linenxt.size() - 1]; cout << lower_bound(sa.begin(), sa.end(), linenxt.c_str(), cmp) - lower_bound(sa.begin(), sa.end(), line.c_str(), cmp) << endl; // beg = bound(true, thetext, line, sa.begin(), sa.end()); // cout << "before bound2"<