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: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CompProgLib;

namespace ALDS1_14_D
{
    public class Program

    {
        public static void Main(string[] args)
        {
            string line = ReadSt();
            int n = ReadInt();
            StringSearch.SuffixArray sa = new StringSearch.SuffixArray(line);

            for (int i = 0 ; i < n ; i++)
            {
                Console.WriteLine(sa.Contains(ReadSt()) ? 1 : 0);
            }
        }

        static string ReadSt() { return Console.ReadLine(); }
        static int ReadInt() { return int.Parse(Console.ReadLine()); }
        static long ReadLong() { return long.Parse(Console.ReadLine()); }
        static double ReadDouble() { return double.Parse(Console.ReadLine()); }
        static string[] ReadStAr(char sep = ' ') { return Console.ReadLine().Split(sep); }
        static int[] ReadIntAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => int.Parse(e)); }
        static long[] ReadLongAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => long.Parse(e)); }
        static double[] ReadDoubleAr(char sep = ' ') { return Array.ConvertAll(Console.ReadLine().Split(sep), e => double.Parse(e)); }

    }

}

namespace CompProgLib
{
    public class StringSearch
    {
        public class SuffixArray
        {
            private string s;
            private int n;
            private int k;
            private int[] rank;
            private int[] sa;

            public SuffixArray(string target)
            {
                s = target;
                n = s.Length;
                sa = new int[n + 1];
                rank = new int[n + 1];
                Constract_sa();
            }

            private int Compare_sa(int i, int j)
            {
                if (rank[i] != rank[j]) return rank[i] - rank[j];
                else
                {
                    int ri = i + k <= n ? rank[i + k] : -1;
                    int rj = j + k <= n ? rank[j + k] : -1;
                    return ri - rj;
                }
            }

            private void Constract_sa()
            {
                for (int i = 0 ; i <= n ; i++)
                {
                    sa[i] = i;
                    rank[i] = (i < n) ? s[i] : -1;
                }

                int[] tmp = new int[n + 1];
                for (k = 1 ; k <= n ; k *= 2)
                {
                    Array.Sort(sa, Compare_sa);

                    tmp[sa[0]] = 0;
                    for (int i = 1 ; i <= n ; i++)
                    {
                        tmp[sa[i]] = tmp[sa[i - 1]] + (Compare_sa(sa[i - 1], sa[i]) < 0 ? 1 : 0);
                    }
                    for (int i = 0 ; i <= n ; i++)
                    {
                        rank[i] = tmp[i];
                    }
                }
            }

            public bool Contains(string pattern)
            {
                int a = 0, b = n;
                while (b - a > 1)
                {
                    int c = (a + b) / 2;
                    if (string.Compare(s, sa[c], pattern, 0, pattern.Length) < 0) a = c;
                    else b = c;

                }
                return string.Compare(s, sa[b], pattern, 0, pattern.Length) == 0;
            }
        }
    }
}