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: Time Limit Exceeded)

#include <stdio.h>
#include <iostream>
#include <algorithm>

using namespace std;

int T_char_count[128] = {0},T_max_succeed_count[128] = {0};

class LocRecord{

public:
	LocRecord(){
		locationTable = new int*[128];
		for(int i = 48; i <= 57; i++){
			if(T_char_count[i] > 0){
				locationTable[i] = new int[T_char_count[i]+1];
			}
		}
		for(int i = 65; i <= 90; i++){
			if(T_char_count[i] > 0){
				locationTable[i] = new int[T_char_count[i]+1];
			}
		}
		for(int i = 97; i <= 122; i++){
			if(T_char_count[i] > 0){
				locationTable[i] = new int[T_char_count[i]+1];
			}
		}

	}

	void init(){

		int limit;

		for(int i = 48; i <= 57; i++){
			if(T_char_count[i] > 0){
				index[i] = 0;
				locationTable[i][T_char_count[i]] = -1;
			}
		}
		for(int i = 65; i <= 90; i++){
			if(T_char_count[i] > 0){
				index[i] = 0;
				locationTable[i][T_char_count[i]] = -1;
			}
		}
		for(int i = 97; i <= 122; i++){
			if(T_char_count[i] > 0){
				index[i] = 0;
				locationTable[i][T_char_count[i]] = -1;
			}
		}

	}

	void init_index(){
		for(int i = 48; i <= 57; i++){
			index[i] = 0;
		}
		for(int i = 65; i <= 90; i++){
			index[i] = 0;
		}
		for(int i = 97; i <= 122; i++){
			index[i] = 0;
		}
	}

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

	int next_loc(int ch){
		int ret = locationTable[ch][index[ch]];
		index[ch]++;
		return ret;
	}

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

void Tcompress(int compressed_array[],char base_array[],int& compressed_length){

    int comp_index = 0,count = 0;
    char ch = base_array[0];

    for(int i = 0; base_array[i] != '\0';){

        if(ch == base_array[i]){
            count++;
            T_char_count[ch]++;
            if(base_array[i+1] == '\0'){
            	T_max_succeed_count[ch] = std::max(T_max_succeed_count[ch],count);
                if(count >= 4){
                    compressed_array[comp_index-2] = -1;
                    compressed_array[comp_index-1] = count;
                }else{
                    compressed_array[comp_index++] = ch;
                }
            }else{
                if(count <= 3){
                    compressed_array[comp_index++] = ch;
                }
            }
            i++;
        }else{
        	T_max_succeed_count[ch] = std::max(T_max_succeed_count[ch],count);
            if(count >= 4){
                compressed_array[comp_index-2] = -1;
                compressed_array[comp_index-1] = count;
            }
            count = 0;
            ch = base_array[i];
        }
    }
    compressed_length = comp_index;
}

int Pcompress(int compressed_array[],char base_array[],int P_char_count[],int& multFLG,int P_max_succeed_count[]){

    int comp_index = 0,count = 0;
    char ch = base_array[0];

    for(int i = 0; base_array[i] != '\0';){

    	if(ch == base_array[i]){
            count++;
            P_char_count[ch]++;
            if(base_array[i+1] == '\0'){
            	P_max_succeed_count[ch] = std::max(P_max_succeed_count[ch],count);
                if(count >= 4){
                    compressed_array[comp_index-2] = -1;
                    compressed_array[comp_index-1] = count;
                }else{
                    compressed_array[comp_index++] = ch;
                }
            }else{
                if(count <= 3){
                    compressed_array[comp_index++] = ch;
                }
            }
            i++;
        }else{
        	P_max_succeed_count[ch] = std::max(P_max_succeed_count[ch],count);
            if(count >= 4){
                compressed_array[comp_index-2] = -1;
                compressed_array[comp_index-1] = count;
            }
            count = 0;
            ch = base_array[i];
            multFLG = 1;
        }
    }
    return comp_index;
}

int main(){
    int T_comp_index,P_comp_index,comp_T_length,tmp,Q,P_length,P_char_count[128],div_tmp;

    char* T = new char[1000001];
    int* compressedT = new int[1000001];

    char P[1001];

    scanf("%s",T);
    Tcompress(compressedT,T,comp_T_length);

    //printf("Tmaxsuceedcount[i] %d:Tmaxsuceedcount[o] %d\n",T_max_succeed_count['i'],T_max_succeed_count['o']);return 0;

    LocRecord loc_record;
    loc_record.init();

    /*for(int i = 0; i < comp_T_length; i++){
    	printf("compressedT[%d]:%c\n",i,compressedT[i]);
    }
    return 0;*/

    scanf("%d",&Q);
    int* possibilityTable = new int[Q];	//0??????????????§?????? 1:???????????£??? 2:????????§??????
    int** compressedP = new int*[Q];

	int* comp_P_length = new int[Q];
	int* leftsuceedFLG = new int[Q];	//1????????£?¶?
	int* rightsuceedFLG = new int[Q];	//1????????£?¶?
	int* multFLG = new int[Q];	//1???????????°
	int* most_right = new int[Q];	//?????????????????????ASCII?????????
	int** P_max_succeed_count = new int*[Q];
	int** moveLength = new int*[Q];//Q????????§?????????????????????????????????Q???????§??????¨?????????

	loc_record.regist_loc(compressedT[0],0);
	for(int i = 1; i < comp_T_length; i++){
	 if(compressedT[i] != -1 && compressedT[i-1] != -1){
		 loc_record.regist_loc(compressedT[i],i);
	 }
	}


	// loc_record.deBug();return 0;
	 /*int buf_fix;
	 loc_record.init_index();
	 while((buf_fix = loc_record.next_loc('b')) != -1 &&  buf_fix  != 0){
		if('b' != compressedT[buf_fix]){
			printf("b??¨??????%c????????????????????????\n",compressedT[buf_fix]);
		}
	 }
	 return 0;*/


    for(int i = 0; i < Q; i++){
    	scanf("%s",P);

    	P_length = 0;
    	moveLength[i] = new int[128];
		P_max_succeed_count[i] = new int[128];
		for(int k = 0; k < 128; k++){
			P_max_succeed_count[i][k] = 0;
			moveLength[i][k] = -1;
			P_char_count[k] = 0; //P???????????°????????????????????????????????????
		}
		multFLG[i] = leftsuceedFLG[i] = rightsuceedFLG[i] = possibilityTable[i] = 0;


		//P?????§???????????????????????°????????´??°???????????????
    	for(int k = 0; P[k] != '\0'; k++) P_length++;	//P???????????°?????°??????
    	compressedP[i] = new int[P_length];	//P????????????????????¢???????????????
    	comp_P_length[i] = Pcompress(compressedP[i],P,P_char_count,multFLG[i],P_max_succeed_count[i]); //??§???&??????????????´?????°???????????????&????????????????????????????????????
    	for(int k = 0; k < 128; k++){
    		if((T_char_count[k] < P_char_count[k]) || (T_max_succeed_count[k] < P_max_succeed_count[i][k])){	//?????´????????????????°?????????¨???P????????´???????????????????????????????????????????????´?????°??\????????????????????????????????????
    			possibilityTable[i] = 2;	//?????????P?????£?¶???????????????\??????T??§??£?¶????????????????????????????
    			break;
    		}
    	}


    	if(multFLG[i] == 0 && possibilityTable[i] == 0) possibilityTable[i] = 1;	//1?¨??????§??????????????°?????´?????°?????????????????????????????????????????????????????§??£?¶??????°????????????????????£????????????????´¢?????????

    	if(possibilityTable[i] == 0){	//?????´??????????????§??????????????????????§??????¨?????????????????????????????£?¶?????????°????????????

    		most_right[i] = P[P_length-1];
    		if(comp_P_length[i] > 2 && compressedP[i][comp_P_length[i]-2] == -1){
    			rightsuceedFLG[i] = 1;
    		}
    		//1????????§?????´??????????????\????????????????????´??§?????\??????????????????????????§?????????2????????\???
    		if(compressedP[i][1] == -1){
    		    leftsuceedFLG[i] = 1;
    		}
    	}
    }

    //printf("Pmaxsuceedcount[0][i] %d:Pmaxsuceedcount[0][o] %d\n",P_max_succeed_count[0]['i'],P_max_succeed_count[0]['o']);
    //printf("Pmaxsuceedcount[1][i] %d:Pmaxsuceedcount[1][o] %d\n",P_max_succeed_count[1]['i'],P_max_succeed_count[1]['o']);return 0;


    /*for(int i = 0; i < comp_P_length[0]; i++){
    	printf("compressedP[%d] = %c\n",i,compressedP[0][i]);
    }*/

    /*for(int i = 0; i < 128; i++){
    	printf("%c:%d\n",i,moveLength[0][i]);
    }
    return 0;
*/
    for(int i = 0; i < Q; i++){
    	if(possibilityTable[i] == 2){	//?????´??????????????§???????????´???
    		printf("0\n");
    	}else if(possibilityTable[i] == 1){	//???????????£?????´???
    		printf("1\n");
    	}else{
			loc_record.init_index();
			T_comp_index = loc_record.next_loc(most_right[i]);
			//printf("most_right???%c??§T_comp_index???????????????%d\n",most_right[i],T_comp_index);
			//printf("%c???????????´???%d\n",most_right[i],first_appeard[most_right[i]]);return 0;
			//printf("???????????°???%d\n",rightsuceedFLG[i]);return 0;
			//printf("???????????°???%d\n",leftsuceedFLG[i]);return 0;

			while(T_comp_index < comp_T_length){
					tmp = T_comp_index;
					P_comp_index = comp_P_length[i]-1;
					//printf("????????????????????????%d\n",comp_P_length[i]);return 0;
					//printf("??????????§???????%c\n",compressedT[T_comp_index]);

					while(P_comp_index >= 0 && tmp >= 0){

						//printf("P_comp_index:%d,tmp:%d\n",P_comp_index,tmp);
						if(tmp == T_comp_index){
							if(rightsuceedFLG[i] == 1){	//compressedP??????????????§??????????????????????????????compressedP?????§?????°?????????????????´???
								if((tmp < comp_T_length - 2) && (compressedT[tmp+1] == -1) && (compressedT[tmp+2] >= compressedP[i][comp_P_length[i]-1])){
									tmp -= 1;
									P_comp_index -= 3;
								}else{
									break;
								}
							}else{	//P??????????????§???????????????????????´???
								if((tmp < comp_T_length - 2) && (compressedT[tmp+1] == -1)){	//T??????????????§????????????????????´???<<compressedT[tmp] == most_right[i]??§????????????>>
									if(compressedP[i][P_comp_index] != compressedP[i][P_comp_index-1]){	//P????????????1?????????????????? <<?????°?????????2????????\???>>
										tmp--;
										P_comp_index--;
									}else if((compressedP[i][P_comp_index] == compressedP[i][P_comp_index-1]) && (compressedP[i][P_comp_index-1] != compressedP[i][P_comp_index-2])){
										tmp--;	//P????????????2???????????´???<<?????°?¨????????????????2???????????´??????3????????\???>>
										P_comp_index -= 2;
									}else{	//P????????????3???????????´???
										tmp--;
										P_comp_index -= 3;
									}
								}else{	//T??????????????§????????????????????´???
									//printf("?????????OK\n");
									tmp--;
									P_comp_index--;
								}
							}
						}else if(leftsuceedFLG[i] == 1 && P_comp_index == 2){	//??????????????????????????§?????????????????????Pmost_left?????§?????°??????????????????????????\???????????´???
							if((tmp > 1) && (compressedT[tmp-1] == -1) && (compressedT[tmp] >= compressedP[i][P_comp_index]) && (compressedP[i][0] == compressedT[tmp-2])){	//T??????????????§????????????????????´???
								tmp -= 3;
								P_comp_index -= 3;
							}else{	//T??????????????§???????????????????????´???
								break;
							}
						}else if((leftsuceedFLG[i] == 0) && (P_comp_index == 2) && (compressedP[i][2] == compressedP[i][1]) && (compressedP[i][1] == compressedP[i][0])){ //??????????????????????????§??????????????????????????????3????????£?¶??????´???
							if((tmp >= 2) && (compressedT[tmp-1] == -1) && (compressedT[tmp-2] == compressedP[i][0])){ //T??????????????§?????????????????????????????´
								tmp -= 3;
								P_comp_index -= 3;
							}else if(compressedP[i][P_comp_index] == compressedT[tmp] && tmp > 1 && compressedT[tmp] == compressedT[tmp-1] && compressedT[tmp-1] == compressedT[tmp-2]){ //T???????????????????????´
								tmp -= 3;
								P_comp_index -= 3;
							}else{
								break;
							}
						}else if((leftsuceedFLG[i] == 0) && (P_comp_index == 1) && (compressedP[i][1] == compressedP[i][0])){	//??????????????????????????§??????????????????????????????2????????£?¶??????´???
							//printf("?????§???????????????2??£?¶?\n");
							if((tmp >= 2) && (compressedT[tmp-1] == -1) && (compressedT[tmp-2] == compressedP[i][0])){ //T?????§?????????????????????????????´
								tmp -= 3;
								P_comp_index -= 2;
							}else if((compressedP[i][P_comp_index] == compressedT[tmp]) && (tmp > 1)  && (compressedT[tmp-1] != -1) && (compressedT[tmp-2] != -1) && (compressedT[tmp] == compressedT[tmp-1])){
								tmp -= 2;
								P_comp_index -= 2;
							}else if((compressedP[i][P_comp_index] == compressedT[tmp]) && (tmp == 1)  && (compressedT[tmp-1] != -1) && (compressedT[tmp] == compressedT[tmp-1])){
								tmp -= 2;
								P_comp_index -= 2;
							}else{
								break;
							}

						}else if((leftsuceedFLG[i] == 0) && (P_comp_index == 0) && (tmp >= 2) && (compressedT[tmp-1] == -1) //??????????????????????????§??????????????????????????????1???????????????T??????????????§???
								&& (compressedT[tmp-2] == compressedP[i][P_comp_index])){
							tmp -= 3;
							P_comp_index--;
						}else{
							if(compressedP[i][P_comp_index] == compressedT[tmp]){
								tmp -= 1;
								P_comp_index--;
							}else{
								//printf("?????£?????????%c??¨%c\n",compressedP[i][P_comp_index],compressedT[tmp]);
								break;
							}
						}
					}

					if(P_comp_index == -1){
						printf("1\n");
						break;
					}

					/*int shishimaru;
					for(shishimaru = T_comp_index + 1; shishimaru < comp_T_length && compressedT[shishimaru] != most_right[i]; shishimaru++){

					}
					T_comp_index = shishimaru;*/

					div_tmp = loc_record.next_loc(most_right[i]);
					//printf("?¬????%d\n",div_tmp);
					if(div_tmp == -1){	//??????compressedT???most_right????????´???????????´???
						printf("0\n");
						break;
					}else{
						T_comp_index = div_tmp;
					}
				}
			if(T_comp_index >= comp_T_length){
				printf("0\n");
			}

    	} //????????????????????§???????????´???????????¬??§
    }	//for???????????¬??§

    return 0;
}