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 <stdio.h>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <set>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define PRIME1 99999883
#define PRIME2 99999893
#define EPS 0.00000001
#define NUM 48
using namespace std;

int T_char_count[128] = {0},P_char_count[128];
int T_Chain[128][128];

class LocRecord{

public:
	//?????¢???????¢????
	LocRecord(){
		locationTable = new int**[128];
		for(int i = 0; i < 128; i++){
			locationTable[i] = new int*[128];
			for(int k = 0; k < 128; k++){
				if(T_Chain[i][k] > 0){
					locationTable[i][k] = new int[T_Chain[i][k]+1];
					for(int p = 0; p < T_Chain[i][k]+1; p++){
						locationTable[i][k][p] = -1;
					}
				}else{
					locationTable[i][k] = new int[2];
					for(int p = 0; p < 2; p++){
						locationTable[i][k][p] = -1;
					}
				}
			}
		}
		init();
	}

	//-1?????£??\
	void init(){
		for(int i = 0; i < 128; i++){
			for(int k = 0; k < 128; k++){
				index[i][k] = 0;
			}
		}
	}

	void init_index(char first,char second){
		index[first][second] = 0;
	}

	void regist_loc(char first,char second,int location){
		locationTable[first][second][index[first][second]] = location;
		index[first][second]++;
	}

	int next_loc(char first,char second){
		int ret = locationTable[first][second][index[first][second]];
		index[first][second]++;
		return ret;
	}

private:
	int*** locationTable;
	int index[128][128];
};

struct Info{
	bool operator<(const struct Info &arg) const{
				return length < arg.length;
	};
	Info(int arg_length,int arg_id,ull arg_hashValue){
		length = arg_length;
		id = arg_id;
		hashValue = arg_hashValue;
	}

	int length,id;
	ull hashValue;
};

int main(){

	for(int i = 0; i < 128; i++){
		T_char_count[i] = 0;
		for(int k = 0; k < 128; k++){
			T_Chain[i][k] = 0;
		}
	}

	int T_length;

	char* T = new char[1000001];
	scanf("%s",T);

	char pre = T[0];
	T_char_count[T[0]]++;

	for(T_length = 1; T[T_length] != '\0';T_length++){
		T_char_count[T[T_length]]++;
		T_Chain[pre][T[T_length]]++;
		pre = T[T_length];
	}

	LocRecord locRecord;
	locRecord.init();


	pre = T[0];
	//T[i]????????????i??§???????????¨????¨????
	for(int i = 1; i < T_length; i++){
		locRecord.regist_loc(pre,T[i],i-1);
		pre = T[i];
	}

	ull* HASH = new ull[T_length+1];
	ull* P = new ull[T_length+1];

	HASH[0] = 0;
	P[0] = 1;

	//T??????????????\???????±???????
	for(int i = 1; i <= T_length; i++){
		HASH[i] = T[i-1] + HASH[i-1]*MOD;
		P[i] = P[i-1]*MOD;
	}


	vector<Info> V[128][128];
	vector<int> LENG[128][128];

	int Q,S_length,left,P_char_count[128];
	scanf("%d",&Q);

	bool check[Q];

	for(int i = 0; i < Q; i++)check[i] = false;

	char S[1001];
	ull S_HASH[1001],S_value,T_value,D;
	bool FLG,isExist;


	//Q??¶??????????????\???????¨????
	for(int loop = 0; loop < Q; loop++){
		scanf("%s",S);

		for(int i = 0; i < 128; i++){
			P_char_count[i] = 0;
		}

		for(S_length = 0;S[S_length] != '\0';S_length++){
			P_char_count[S[S_length]]++;
		}

		FLG = true;

		for(int i = 0; i < 128; i++){
			if(T_char_count[i] < P_char_count[i]){
				FLG = false;
				break;
			}
		}
		if(!FLG)continue;

		if(S_length == 1){
			check[loop] = true;
			continue;
		}



		S_HASH[0] = 0;
		for(int i = 1; i <= S_length; i++){
			S_HASH[i] = S[i-1] + S_HASH[i-1]*MOD;
		}

		S_value = S_HASH[S_length];

		V[S[0]][S[1]].push_back(Info(S_length,loop,S_value));

		isExist = false;
		for(int i = 0; i < LENG[S[0]][S[1]].size();i++){
			if(LENG[S[0]][S[1]][i] == S_length){
				isExist = true;
				break;
			}
		}

		if(!isExist){
			LENG[S[0]][S[1]].push_back(S_length);
		}
	}

	int calc_length,calc_left,calc_right,calc_m;

	vector<ull> TEMP[1001];

	for(int first_word = 48; first_word <= 122; first_word++){
		for(int second_word = 48; second_word <= 122;second_word++){
			for(int i = 0; i < LENG[first_word][second_word].size();i++){
				calc_length = LENG[first_word][second_word][i];
				TEMP[calc_length].clear();

				locRecord.init_index(first_word,second_word);

				//???????????\?????????????¨????????????????
				while((left = locRecord.next_loc(first_word,second_word)) != -1){
					if(left+calc_length-1 >= T_length)break;

					TEMP[calc_length].push_back(HASH[left+calc_length]-HASH[left]*P[calc_length]);
				}
			}

			//???????????\??????sort
			for(int i = 0; i < LENG[first_word][second_word].size();i++)sort(TEMP[LENG[first_word][second_word][i]].begin(),TEMP[LENG[first_word][second_word][i]].end());

			for(int i = 0; i < V[first_word][second_word].size();i++){

				calc_length = V[first_word][second_word][i].length;
				S_value = V[first_word][second_word][i].hashValue;

				calc_left = 0;
				calc_right = TEMP[calc_length].size()-1;
				calc_m = (calc_left+calc_right)/2;
				while(calc_left <= calc_right){

					if(TEMP[calc_length][calc_m] == S_value){
						check[V[first_word][second_word][i].id] = true;
						break;
					}else{
						if(TEMP[calc_length][calc_m] < S_value){
							calc_left = calc_m+1;
						}else{
							calc_right = calc_m-1;
						}
					}
					calc_m = (calc_left+calc_right)/2;
				}
			}
		}
	}

	for(int i = 0; i < Q; i++){
		if(check[i])printf("1\n");
		else{
			printf("0\n");
		}
	}

	return 0;
}