Problem:
String Search

Determine whether a text T includes a pattern P. Your program should answer for given queries consisting of P_i.

Input

In the first line, a text T is given. In the second line, an integer Q denoting the number of queries is given. In the following Q lines, the patterns P_i are given respectively.

Output

For each question, print 1 if the text includes P_i, or print 0 otherwise.

Constraints

1 ≤ length of T ≤ 1000000

1 ≤ length of P_i ≤ 1000

1 ≤ Q ≤ 10000

The input consists of alphabetical characters and digits

Sample Input 1

aabaaa
4
aa
ba
bb
xyz

Sample Output 1

1
1
0
0

Solution in C++ (judge verdict: Memory Limit Exceeded)

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<climits>
#include<cstring>
#include<queue>
#include<map>
#include<complex>
#include<typeinfo>
using namespace std;

vector<bool> match(20000, false);

struct Node{
    string pat;
    map<char, int> child;
    int fail;
    bool blue;
    vector<int> patternNum;
};

bool mapElementCheck(map<char, int> &child, char &c){
    return child.find(c) != child.end();
}

void concatStringVector(vector<string> &v1, vector<string> &v2){
    v1.insert(v1.begin(), v2.begin(), v2.end());
}

void concatIntVector(vector<int> &v1, vector<int> &v2){
    v1.insert(v1.begin(), v2.begin(), v2.end());
}

void printNode(Node &n){
    cout << endl << "pat: " << n.pat << endl;
    cout << "child: " << endl;
    for (map<char, int>::iterator itr = (n.child).begin();itr!=(n.child).end();itr++){
        cout << itr->first << " " << itr->second << endl;
    }
    cout <<"fail: " << n.fail << endl;
    cout << "blue: " << n.blue << endl;
    cout << "patternNum: " <<endl;
    for (int i=0;i<(n.patternNum).size();i++){
        cout << (n.patternNum)[i] << endl;
    }
    cout << endl;
    return;
}

void insert(vector<Node> &nodes, string &S, int patternNum){
    int now = 0;
    for (int i=0;i<S.size();i++){
        map<char, int>& mp = nodes[now].child;
        if(mp.find(S[i]) == mp.end()){
            Node n;
            n.pat = nodes[now].pat + string(1, S[i]);
            nodes.push_back(n);
            (nodes[now].child)[S[i]] = nodes.size()-1;
            now = nodes.size()-1;
        }else{
            now = mp[S[i]];
        }
        if(i == S.size()-1){
                nodes[now].blue = true;
                (nodes[now].patternNum).push_back(patternNum);
            }else{
                nodes[now].blue = false;
            }
    }
    return;
}

void makeFailure(vector<Node> &nodes){
    queue< pair<int, int> > qu;
    qu.push(make_pair(0, 0));
    while(!qu.empty()){
        pair<int, int> now = qu.front();
        qu.pop();
        for (map<char, int>::iterator itr = (nodes[now.first].child).begin();itr!=(nodes[now.first].child).end();itr++){
            qu.push(make_pair( itr->second, now.first));
        }
        if(now.second == 0 || now.first == 0){
            nodes[now.first].fail = 0;
        }else{
            string tmpStr = (nodes[now.first]).pat;
            char last = tmpStr[tmpStr.size()-1];
            int ances = nodes[now.second].fail;
            bool b1 = false;
            while((nodes[ances].child).find(last) == (nodes[ances].child).end()){
                if (ances == 0){
                    b1 = true;
                    break;
                }
                ances = nodes[ances].fail;
            }
            if(b1){
                nodes[now.first].fail = 0;
            }else{
                nodes[now.first].fail = (nodes[ances].child)[last];
                concatIntVector(nodes[now.first].patternNum, nodes[nodes[now.first].fail].patternNum);
            }
        }
    }
}

vector<Node> makePMA(vector<string> &P){
    vector<Node> nodes;
    Node n0;
    n0.blue = false;
    nodes.push_back(n0);
    for (int i=0;i<P.size();i++){
        insert(nodes, P[i], i);
    }
    makeFailure(nodes);
    return nodes;
}

void PMASesch(vector<Node> &PMA, string &P){
    int now = 0;
    for (int i=0;i<P.size();i++){
        if(!mapElementCheck(PMA[now].child, P[i])){
            while(!mapElementCheck(PMA[now].child, P[i])){
                if(now == 0) break;
                now = PMA[now].fail;
            }
        }
        if (mapElementCheck(PMA[now].child, P[i])){
            now = (PMA[now].child)[P[i]];
            for (int j=0;j<(PMA[now].patternNum).size();j++){
                match[(PMA[now].patternNum)[j]] = true;
            }
        }else{
            now = 0;
        }
    }
}

int main(){
    string T;
    cin >> T;
    int Q;
    cin >> Q;
    vector<string> P;
    string tmp;
    for (int i=0;i<Q;i++){
        cin >> tmp;
        P.push_back(tmp);
    }
    vector<Node> PMA = makePMA(P);
    /*
    for (int i=0;i<PMA.size();i++){
        printNode(PMA[i]);
    }
    cout << "makePMA: end" << endl;
    */
    PMASesch(PMA, T);
    /*
    cout << "searchPMA: end" << endl;
    */
    for (int i=0;i<Q;i++){
        cout << match[i] << endl;
    }

    return 0;
}