Maximum repetition substring – Suffix Array

The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of “ababab” is 3 and “ababa” is 1.

Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.

Link : Problem

Solution :

O(n^2) Solution:

    Use KMP for each suffix.Then determine the maximum repeatating for each. Output the maximum. But to find the leaxographically smallest , We need to do some other works.

    Pseudocode:

    iM = 0;
    for each suffix starting from i to strlen(s)
             temp= Maximum Repeatation in this suffix
             iM= max(iM , temp) ;
    

N log N Solution :

    First Build the suffix array and LCP array.
    Every Repating String is in form S = A^k , A is concatanated k times to form this string.
    Let, len be possible length of A such that A can form a substring of S by concatanating 1 or moretime.
    for each length We do the following.
    IMG_20160131_022136
    Only keep the values That produces maximum k
    To find the lexicographic minimal string, We iterate in the order of the suffix array and check whether it generates a Repeating string with maximum k. If it is then Store the position and break
    output the substring

    Here is my code:

    /*
     *************************
     Id  : Matrix.code
     Task: HDU 2459
     Date: 2016-01-30
    
     **************************
     */
    
    
    #include <bits/stdc++.h>
    using namespace std;
    
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/tree_policy.hpp>
    using namespace __gnu_pbds;
    template <typename T>
    using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
    
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1e5+5;
    
    int wa[N],wb[N],wv[N],wc[N];
    int r[N],sa[N],rak[N], height[N];
    
    // compare of two suffix starting at a & b and gap = l
    int cmp(int *r,int a,int b,int l)
    {
          return r[a] == r[b] && r[a+l] == r[b+l];
    }
    void da(int *r,int *sa,int n,int m)
    {
          int i,j,p,*x=wa,*y=wb,*t;
          for( i=0;i<m;i++) wc[i]=0;
          for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
          for( i=1;i<m;i++) wc[i] += wc[i-1];
          for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
          for( j= 1,p=1;p<n;j*=2,m=p){
                for(p=0,i=n-j;i<n;i++)y[p++] = i;
                for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
                for(i=0;i<n;i++)wv[i] = x[y[i]];
                for(i=0;i<m;i++) wc[i] = 0;
                for(i=0;i<n;i++) wc[wv[i]] ++;
                for(i=1;i<m;i++) wc[i] += wc[i-1];
                for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
                for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
    
          }
    }
    
    void calheight(int *r,int *sa,int n)
    {
    
          int i,j,k=0;
          for(i=1;i<=n;i++) rak[sa[i]] = i;
          for(i=0;i<n;height[rak[i++]] = k ) {
    
                for(k?k--:0, j=sa[rak[i]-1] ; r[i+k] == r[j+k] ; k ++) ;
          }
    
    }
    int dp[N][20];
    void initRMQ(int n)
    {
          for(int i= 1; i <= n; i ++) dp[i][0] = height[i];
          for(int j= 1; 1<< j <= n ; j ++ ){
                for(int i= 1; i+(1<<j)-1 <= n ; i ++ ) {
                      dp[i][j] = min(dp[i][j-1] , dp[i+(1<<(j-1))][j-1]);
                }
          }
    }
    int askRMQ(int L,int R)
    {
          if(L>R)swap(L,R);
          L ++;
          int k = 0;
          while((1<<(k+1)) <= R-L+1) k++;
          return min(dp[L][k], dp[R - (1<<k) + 1][k]);
    }
    char str[N];
    
    int main()
    {
          //freopen("in.txt","r",stdin);
          int cs=  0;
          while(scanf("%s",str)) {
                if(str[0]=='#') break;
                int p = strlen(str);
                for(int i= 0; str[i]; i ++ ) {
                      r[i] = str[i] - 'a' + 1;
                }
                r[p] = 0;
                da(r,sa,p+1,32);
                calheight(r,sa,p);
                initRMQ(p);
                int n = p;
                vector<int> v;
                int iM = 1;
                /*
                for(int i = 0; i <= p; i ++) printf("%d ", sa[i]);puts("");
                for(int i = 0; i <= p; i ++) printf("%d ",height[i]);puts("");
                for(int i = 0;i <= p; i ++) printf("%d ",rak[i]);*/
                for(int len = 1;len  <= n; len ++ ) {
                      for(int i = 0; i + len < n ; i += len ) {
                            int k = askRMQ(rak[i], rak[i+len] );
                            
                            int step = k / len + 1;
                            int fix = i - (len - k % len) ;
                            if(fix >= 0 && k % len ) {
                                  int noo = askRMQ(rak[fix], rak[fix + len] ) ;
    
                                  step = max(step, noo / len + 1);
                            }
                            
                            if(step > iM ){
                                  v.clear();
                                  v.pb(len);
                                  iM=step;
                            }else if(step== iM) {
                                  v.pb(len);
                            }
    
                      }
                }
                v.push_back(1);
                sort(all(v));
                v.resize(unique(all(v)) - v.begin());
                int pos = 0;
                int Len = -1;
    
    
                for(int i= 1; i <= n && Len == -1 ; i ++ ) {
                      for(int j= 0; j < v.size(); j ++ ) {
                            int len = v[j];
                            int ans = askRMQ(i, rak[sa[i] + len]) ;
    
                            if(ans >= (iM - 1) * len) {
                                   pos = sa[i];
    
                                   Len = iM * len;
                                   break;
                            }
                      }
    
                }
                printf("Case %d: ",++cs);
                for(int i = 0; i < Len; i ++ ) printf("%c" , str[pos +i ]);
                printf("\n");
          }
          return 0;
    
    }
    
    

    Codeforces – 375D

    The problem is a great learning.It helped me to implement MO’s algorithm and also Union By Rank.
    First Solution : MO’s Algorithm.

      Euler tour in the tree.Determine the range of a subtree of a node
      Sort the query according to MO’S algorithm.
      For each addition, Update how many times the added colour appeared in the range, Update a bit for range query.
      For deletion, Decrease the count of the colour, also update the bit.
      For answer, query in the bit and calculate how many number in range [k,MAX]

    /*
    
     *************************
     Id  : Matrix.code
     Task: 375D
     Date: 2016-01-26
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1e5+5;
    int w[N];
    int L[N],R[N] ,cnt = -1 ,ar[N] , c[N];
    bool vis[N];
    int block;
    int occ[N];
    int pos[N];
    vector<int> G[N];
    struct Query{
          int l,r,k,i;
          bool operator<(const Query &q ) const {
                if(l/block == q.l/ block) return r < q.r;
                else return l < q.l;
          }
    };
    vector<Query> q;
    void dfs(int u)
    {
          vis[u] = 1;
          L[u] = ++cnt;
          ar[cnt] = c[u];
          for(auto a: G[u]) if(vis[a]== 0) {
                dfs(a);
          }
          R[u] = cnt;
    
    }
    int b[N];
    
    void update(int x,int v)
    {
          for(;x<N;x+=x&-x) b[x] += v;
    }
    int query(int x)
    {
    
          int ret = 0;
          for(; x>0; x-=x&-x) ret += b[x];
          return ret;
    }
    void add(int ind)
    {
          int v = ar[ind];
          int now = pos[v];
          if(now) {
                update(now,-1);
                occ[now] --;
          }
          pos[v] = now +1;
          occ[pos[v]] ++;
          update(pos[v] ,1);
    }
    
    void del(int ind)
    {
          int v= ar[ind];
          int now = pos[v];
          if(now) {
                update(now,-1);
                occ[now] --;
                pos[v] = now - 1;
          }
          if(pos[v]) {
                occ[pos[v]] ++;
                update(pos[v],1);
          }
    }
    int ans[N];
    int main()
    {
          //freopen("in.txt","r",stdin);
    
          Dii(n,m);
          for(int i= 1; i<= n; i ++) {
                Si(c[i]);
          }
          for(int i= 0;i < n-1;i ++ ) {
                Dii(a,b);
                G[a].push_back(b);
                G[b].push_back(a);
          }
          block = sqrt(n) + 1;
          dfs(1);
          for(int i= 0; i<  m; i ++ ) {
                Dii(u,k);
                q.push_back({L[u],R[u],k,i});
          }
          sort(all(q));
          int curl = 0, curr = 0;
          for(int i= 0;i < q.size(); i ++ ) {
                int L=  q[i].l, R = q[i].r;
    
    
                while(curl > L) {add(curl-1),curl--;}
                while(curr <=R) {add(curr),curr++;}
                while(curl < L) {del(curl), curl++;}
                while(curr>R+1) {del(curr-1),curr--;}
                ans[q[i].i] = query(N-1) - query(q[i].k-1);
          }
          for(int i= 0;i < SZ(q); i ++ ) {
                printf("%d\n", ans[i]);
          }
          return 0;
    }
    

    Second Solution : Union By Rank.

      Take all the query and store them separately for each node
      dfs traversal of the tree and Merge two subtree according to their size
      while joining two subtree, The number of occurance of a color can increase, We add this to num vector
    /*
     
     *************************
     Id  : Matrix.code
     Task: 375D - Union By Rank
     Date: 2016-01-27
     
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1e5+55;
    vector<int> G[N];
    vector<pair<int,int> > Q[N];
    int c[N];
    int finalAns[N];
    
    struct dta{
          map<int,int> Map;
          vector<int> num; // num[i] determines how many color have >=i occurance
          
          dta(int c){
                Map[c] = 1;
                num.push_back(0);
                num.push_back(1);
          }
    };
    dta * T[N];
    
    void Merge(int a,int b)
    {
          if(T[a]->Map.size() < T[b]->Map.size() ){
                dta * temp = T[a];
                T[a] = T[b];
                T[b] = temp;
          }
          for(auto i : T[b]->Map) {
                int c = i.first,n = i.second;
                int already = T[a]->Map[c];
                for(int j = already + 1; j <= already + n ; j ++ ) {
                      if(j>=T[a]->num.size()) T[a]->num.push_back(0);
                      T[a]->num[j] ++;
                }
                T[a]->Map[c] += n;
          }
          
    }
    void dfs(int u,int p=-1)
    {
          T[u] = new dta(c[u]);
          
          for(auto a : G[u]) if(a!=p) {
                dfs(a,u);
                Merge(u,a);
          }
          for(int i= 0;i < SZ(Q[u]); i ++ ) {
                int k = Q[u][i].first, ind = Q[u][i].second;
                if(k >= T[u]->num.size()) finalAns[ind] = 0;
                else finalAns[ind] = T[u]->num[k];
          }
          
    }
    
    int main()
    {
          //freopen("in.txt","r",stdin);
          
          Dii(n,m);
          for(int i= 1; i<= n; i ++) {
                Si(c[i]);
          }
          for(int i= 0;i < n-1;i ++ ) {
                Dii(a,b);
                G[a].push_back(b);
                G[b].push_back(a);
          }
          for(int i= 0;i < m; i ++ ) {
                Dii(v,k);
                Q[v].push_back(mp(k,i));
          }
          dfs(1);
          for(int i= 0;i < m; i ++ ) {
                printf("%d\n",finalAns[i]);
          }
          return 0;
    }
    

    Union By Rank

    Union By Rank is common Technique in Disjoint-Set.
    The application of this technique is needed for Kruskal’s Minimum Spanning Tree.
    Normal Kruskal Code using path-compression would look like this .

    void init(int n)
    {
          for(int i = 1;i <= n;i ++) p[i] = i;
    }
    int find(int u)
    {
    	if(p[u]==u) return u;
    	else return p[u] = find(p[u]);
    }
    void Merge(int a,int b)
    {
    	int u = find(a);
    	int v = find(b);
    	if(u!=v) {
    		p[u] = v ; // p[v] = u both are correct
    	}
    }
    

    Union By Rank is Simillar to this But We use rank to determine of the new parent.
    Rank can be the size of the set.
    So the modified code would be

    void init(int n)
    {
         for(int i= 1;i <= n; i ++ ) p[i] = i,R[i] = 1;
    }
    int find(int u)
    {
    	if(p[u]==u) return u;
    	else return p[u] = find(p[u]);
    }
    void Merge(int a,int b)
    {
    	int u = find(a);
    	int v = find(b);
    	if(u!=v) {
    		if(R[u] > R[v]) {
    			P[v] = u;
    			R[u] += R[v];
    		}
    		else {
    			P[u] = v;
    			R[v] += R[u];
    		}
    	}
    }
    
    

    Now this technique can be used to particular different kind of problems :

    Problem : Link
    Discussion From Codeforces Tutorial:

    The name of this problem is anagram for ”Small to large”. There is a reason for that 🙂 The author solution for this problem uses the classic technique for computing sets in tree. The simple solution is the following: let’s find for each vertex v the ”map” — the number of occurences for each colour, ”set<pair>” — pairs the number of occurences and the colour, and the number sum — the sum of most frequent colours in subtree of v. To find that firstly we should find the same thing for all childs of v and then merge them to one. These solution is correct but too slow (it works in O(n^2 * logn) time). Let’s improve that solution: every time when we want to merge two map-s a and b let’s merge the smaller one to larger simply by iterating over all elements of the smaller one (this is the “Small to large”). Let’s consider some vertex v: every time when vertex v will be moved from one map to another the size of the new map will be at least two times larger. So each vertex can be moved not over than logn times. Each moving can be done in O(logn) time. If we accumulate that values by all vertices then we get the complexity O(n(logn)^2).

    I saw the solutions that differs from author’s but this technique can be used in a lot of other problems.

    My code :

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: 600E
     Date: 2016-01-27
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1e5+5;
    map<int,int > T[N];
    int p[N];
    int c[N];
    Long finalAns[N];
    vector<int> G[N];
    Long iMax[N], cnt[N];
    
    void Merge(int a,int b)
    {
          if(SZ(T[p[a]]) < SZ(T[p[b]])) swap(p[a],p[b]);
          int id = p[a];
          for(auto i : T[p[b]]) {
                int col = i.Fr, occ = i.Sc;
                T[id][col] += occ;
                if(T[id][col] > iMax[id] ) {
                      iMax[id] = T[id][col];
                      cnt[id] = col;
                } else if(T[id][col] == iMax[id]) cnt[id] += col;
          }
    }
    void dfs(int u,int par=-1)
    {
          for(auto a: G[u]) if(a!=par) {
                dfs(a,u);
                Merge(u,a);
    
          }
          finalAns [u] = cnt[p[u]];
    }
    int main()
    {
          //freopen("in.txt","r",stdin);
    
          Di(n);
          for(int i= 1;i <= n;i ++ ) {
                Si(c[i]);
                p[i] = i;
                cnt[i] = c[i];
                iMax[i] = 1;
                T[i][c[i]] = 1;
          }
    
          for(int i= 0;i < n-1;i ++ ) {
                Dii(a,b);
                G[a].pb(b);
                G[b].pb(a);
          }
          dfs(1);
          for(int i= 1;i <= n; i++ ) printf("%lld ",finalAns[i]);
          return 0;
    }
    
    

    2D RMQ

    As 1D RMQ is easy to implement.So to 2D RMQ.
    Problem Link : Problem

    
    /*
    
    *************************
    Id  : Matrix.code
    Task: HDU - 2888
    Date: 2016-01-22
    
    **************************
    
    */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){
    	register int c = gc(); x = 0; int neg = 0; for (; ((c<48 | c>57) && c != '-'); c = gc());
    	if (c == '-') { neg = 1; c = gc(); }for (; c>47 && c<58; c = gc()) { x = (x << 1) + (x << 3) + c - 48; }if (neg) x = -x;
    }
    Long bigmod(Long p, Long e, Long M){ Long ret = 1; for (; e > 0; e >>= 1){ if (e & 1) ret = (ret * p) % M; p = (p * p) % M; } return ret; }
    Long gcd(Long a, Long b){ if (b == 0)return a; return gcd(b, a%b); }
    Long modinverse(Long a, Long M){ return bigmod(a, M - 2, M); }
    void io(){ freopen("/Users/MyMac/Desktop/in.txt", "r", stdin); }
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 305;
    int a[N][N];
    int dp[N][N][9][9];
    void initRMQ(int n, int m)
    {
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < m; j++) dp[i][j][0][0] = a[i][j];
    	}
    	for (int p = 0; (1 << p) <= n; p++) {
    		for (int q = 0; (1 << q) <= m ; q++) {
    			if (p + q == 0) continue;
    			for (int i = 0; i + (1<<p)-1 < n; i++) {
    				for (int j = 0; j + (1 << q) - 1 < m; j++) {
    					if (p) dp[i][j][p][q] = max(dp[i][j][p - 1][q], dp[i + (1 << (p-1))][j][p - 1][q]);
    					else dp[i][j][p][q] = max(dp[i][j][p][q-1], dp[i][j+(1<<(q-1))][p][q-1]);
    				}
    			}
    		}
    	}
    }
    
    
    int askRMQ(int x1, int y1, int x2, int y2) {
        int x = 0, y = 0;
        while ((1<<(x+1)) <= x2 - x1 + 1) x++;
        while ((1<<(y+1)) <= y2 - y1 + 1) y++;
        x2 = x2 - (1<<x) + 1;
        y2 = y2 - (1<<y) + 1;
    
          //printf("%d %d %d %d %d %d\n",x1,y1,x2,y2,x,y);
        return max( max(dp[x1][y1][x][y], dp[x2][y1][x][y]), max(dp[x1][y2][x][y], dp[x2][y2][x][y]));
    }
    int main()
    {
    	
    	int n, m;
    	while (scanf("%d %d", &n, &m) == 2) {
    		for (int i = 0; i < n; i++){
    			for (int j = 0; j < m; j++) {
    				scanf("%d", &a[i][j]);
    			}
    		}
    		initRMQ(n, m);
    		Di(q);
    		while(q--) {
                      int x1,x2,y1,y2;
    
                      scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                      x1--,y1--,x2--,y2--;
                      int ans = askRMQ(x1, y1, x2, y2);
                      //db(ans);
                      bool flag = false;
                      if (ans == a[x1][y1] || ans == a[x1][y2] || ans == a[x2][y1] || ans == a[x2][y2])
                          flag = true;
                      printf("%d %s\n", ans, flag ? "yes" : "no");
    		}
    	}
    }
    
    

    Suffix Array & RMQ

    Range Minimum Query is very much common in suffix array problem.
    Notations :

    SA[i] -> ith smallest suffix of the string
    height[i] -> Longest common substring between Suffix(i-1) and Suffix(i)
    rak[i] -> The position of i th index of the main string in height array.

    Problem 1 :
    Given a string. Output the longest common substring of ith suffix and jth suffix.
    Solution : Algorithm Suffix Array.

    L = rak[i], R = rak[j],
    ans = min (height[L+1,R])

    Why L+1 ? Remember the definition of height.

    And how to find RMQ of a static array ??? See topcoder tutorial here

    Sample Problem: UVA- 12338 – Anti-Rhyme Pairs

    My Solution:

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: 12338 - Anti-Rhyme Pairs
     Date: 2016-01-22
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 2e6+5;
    int wa[N],wb[N],wv[N],wc[N];
    int r[N],sa[N],rak[N], height[N];
    
    // compare of two suffix starting at a & b and gap = l
    int cmp(int *r,int a,int b,int l)
    {
          return r[a] == r[b] && r[a+l] == r[b+l];
    }
    void da(int *r,int *sa,int n,int m)
    {
          int i,j,p,*x=wa,*y=wb,*t;
          for( i=0;i<m;i++) wc[i]=0;
          for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
          for( i=1;i<m;i++) wc[i] += wc[i-1];
          for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
          for( j= 1,p=1;p<n;j*=2,m=p){
                for(p=0,i=n-j;i<n;i++)y[p++] = i;
                for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
                for(i=0;i<n;i++)wv[i] = x[y[i]];
                for(i=0;i<m;i++) wc[i] = 0;
                for(i=0;i<n;i++) wc[wv[i]] ++;
                for(i=1;i<m;i++) wc[i] += wc[i-1];
                for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
                for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
    
          }
    }
    
    void calheight(int *r,int *sa,int n)
    {
    
          int i,j,k=0;
          for(i=1;i<=n;i++) rak[sa[i]] = i;
          for(i=0;i<n;height[rak[i++]] = k ) {
    
                for(k?k--:0, j=sa[rak[i]-1] ; r[i+k] == r[j+k] ; k ++) ;
          }
    
    }
    
    
    char s[N];
    int head[N], len[N];
    int dp[N][22];
    void initRMQ(int n)
    {
          for(int i= 1;i<=n;i++) dp[i][0] = height[i];
          for(int j= 1; (1<<j) <= n; j ++ ){
                for(int i = 1; i + (1<<j) - 1 <= n ; i ++ ) {
                      dp[i][j] = min(dp[i][j-1] , dp[i + (1<<(j-1))][j-1]);
                }
          }
    
    }
    int askRMQ(int L,int R)
    {
          int k = 0;
          while((1<<(k+1)) <= R-L+1) k++;
          return min(dp[L][k], dp[R - (1<<k) + 1][k]);
    }
    int main()
    {
          //freopen("in.txt","r",stdin);
    
          Di(t);
          int cs = 0;
          while(t-- ){
                Di(n);
                int cnt = 1;
                int p= 0;
                forn(i,n) {
                      scanf("%s",s);
                      head[i] = p;
                      len[i] = strlen(s);
                      for(int j = 0; s[j] ; j ++ ) {
                            r[p++] = s[j] - 'a' + 1;
                      }
                      r[p++] = i + 27;
                      cnt = max(cnt,r[p-1]);
                }
                p--;
                r[p] = 0;
    
                da(r,sa,p+1,cnt+1);
                //for(int i= 0;i <= p ;i ++) printf("sa[%d]- >%d\n",i ,sa[i]);
                calheight(r,sa,p);
    
                initRMQ(p);
                Di(q);
                printf("Case %d:\n",++cs);
                while(q--) {
                      Dii(a,b);
                      a--,b--;
                      if(a==b) {
                            printf("%d\n", len[a]);
                            continue;
                      }
                      int L = head[a], R= head[b];
                      L = rak[L], R=rak[R];
                      if(L>R) swap(L,R);
    
                      //db(iM);
                      printf("%d\n", askRMQ(L+1,R));
                }
          }
          return 0;
    }
    

    Google Code Jam 2015 – Qualification Round

    Contest Link: Codejam Qualification Round 2015
    Problem A: See the editorial of the problem. Code Jam Editorial

    Solution: The friends invited should have shyness 0 for optimal.
    The solution is shown in the editorial. But We can apply binary search on the ans.
    If we can make things right with k people, then its possible for also k+1, k+2…
    So, applying binary search we can easily solve this problem.

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: A. Standing Ovation
     Date: 2016-01-17
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1005;
    
    char str[N];
    int v[N];
    int tmp[N];
    bool can(int mid,int n)
    {
          for(int i = 0;i <= n;i ++ ) tmp[i] = v[i];
          tmp[0] += mid;
          Long sum = tmp[0];
          for(int j=1;j<=n;j++) {
                if(tmp[j] ==0 ) continue;
                if(sum >= j) sum += tmp[j];
                else return 0;
          }
          return 1;
    }
    int main()
    {
          /*freopen("A-large-practice.in","r",stdin);
          freopen("out.txt","w",stdout);*/
          Di(t);
          int cs = 0;
          while(t--) {
                Di(n);
                scanf("%s",str);
                for(int i= 0;i<=n;i++) v[i] = str[i] -'0';
                int low = 0, high = n * (n+1)/2 , mid, ans=-1;
    
                while(low <= high)
                {
                      mid = (low+high)/2;
                      if(can(mid,n)) {
                            ans = mid;
                            high = mid-1;
                      }else low = mid+1;
    
                }
                printf("Case #%d: %d\n",++cs,ans);
                ms(v,0);
          }
    
          return 0;
    }
    

    Problem B:

    The editorial is well discussed.No need for explain.

    Solution:

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: B. Infinite House of Pancakes
     Date: 2016-01-17
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 2005;
    int n;
    int a[N];
    
    int main()
    {
          /*
          freopen("B-large-practice.in","r",stdin);
          freopen("out.txt","w",stdout); */
          Di(t);
          int cs = 0;
          while(t--) {
                Si(n);
                int iM = 0;
                for(int i =0 ;i < n;i ++ ) {
                      Si(a[i]);
                      iM= max(iM, a[i]);
                }
    
                int ans = iM;
                for(int i=1;i <= iM; i++ ) {
                      int iMin = i;
                      for(int j=0;j<n;j++) {
                            iMin += ceil(1.*a[j] / i) -1;
                      }
                      ans = min(ans,iMin) ;
                }
                printf("Case #%d: %d\n", ++cs , ans);
    
          }
    
          return 0;
    }
    
    
    

    Problem C:
    Editorial: Problem C
    My code:

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: Dijkstra
     Date: 2016-01-17
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 1e5+5;
    enum {I=2,J=3,K=4};
    int Tr[][5] =
    {
          {0,0,0,0,0},
          {0,1,I,J,K},
          {0,I,-1,K,-J},
          {0,J,-K,-1,I},
          {0,K,J,-I,-1}
    };
    int Map[150];
    string str, s;
    int ar[N];
    int prefix[N], suffix[N];
    int mul(int a,int b)
    {
    
          int cnt = 0;
          if(a<0) cnt++ , a=-a;
          if(b<0) cnt ++ , b=-b;
          return (cnt&1) ? -Tr[a][b] : Tr[a][b];
    }
    
    int Mod(Long b,Long p)
    {
          if(p==0)return 1;
          if(p&1) return mul(b,Mod(b,p-1));
          int k = Mod(b,p/2);
          return mul(k,k);
    }
    int main()
    {
          /*freopen("c-large-practice.in","r",stdin);
          freopen("out.txt","w",stdout); */
          Map['i'] = 2,Map['j'] = 3,Map['k']=4;
          Di(t);
          int cs = 0;
          while(t--) {
                Long l,x;
                Sii(l,x);
                cin >> str;
                int Sum = 1;
                forn(i,SZ(str)) {
                      Sum = mul(Sum,Map[str[i]]);
                }
                int k = Mod(Sum,x);
                bool flag = 0;
    
                if(k==-1){
                      forn(i,min(8,x)) {
                            s += str;
                      }
                      int cnt = 0;
                      int Sum = 1;
                      for(int i= 0;i < s.length(); i ++ ) {
                      	Sum = mul(Sum, Map[s[i]]);
                      	if(cnt==0){
                      		if(Sum== I) cnt =1,Sum=1;
                      	}
                      	else if(cnt==1){
                      		if(Sum == J ) {
                      			cnt = 2;
                      			break;
                      		}
                      	}
    
                      }
                      if(cnt==2) flag=1;
                }
                printf("Case #%d: %s\n", ++cs, flag? "YES" : "NO");
                s.clear();
          }
          return 0;
    }
    
    

    Longest Common Substring of different string

    Sample Problem : Life Forms

    Category : Suffix – array
    Solution :

      First copy the string into a new integer array and place a value between them which will never occur in the strings.
      build suffix array and heigth (LCP) array
      Binary search on the length. Find if it is possible to get a substring which have length = mid and occur in > half of the number of string.
      Print the string.

    Now code :

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: 11107 Life Forms
     Date: 2016-01-17
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 2e5+5;
    int wa[N],wb[N],wv[N],wc[N];
    int r[N],sa[N],rak[N], height[N];
    int cmp(int *r,int a,int b,int l)
    {
          return r[a] == r[b] && r[a+l] == r[b+l];
    }
    void da(int *r,int *sa,int n,int m)
    {
          int i,j,p,*x=wa,*y=wb,*t;
          for( i=0;i<m;i++) wc[i]=0;
          for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
          for( i=1;i<m;i++) wc[i] += wc[i-1];
          for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
          for( j= 1,p=1;p<n;j*=2,m=p){
                for(p=0,i=n-j;i<n;i++)y[p++] = i;
                for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
                for(i=0;i<n;i++) wv[i] = x[y[i]];
                for(i=0;i<m;i++) wc[i] = 0;
                for(i=0;i<n;i++) wc[wv[i]] ++;
                for(i=1;i<m;i++) wc[i] += wc[i-1];
                for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
                for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
    
          }
    }
    
    void calheight(int *r,int *sa,int n)
    {
          int i,j,k=0;
          for(i=1;i<=n;i++) rak[sa[i]] = i;
          for(i=0;i<n;height[rak[i++]] = k ) {
                for(k?k--:0, j=sa[rak[i]-1] ; r[i+k] == r[j+k] ; k ++) ;
          }
    }
    
    int id[N];
    vector<int> Pi[N];
    bool can(int mid,int n,int type,int k)
    {
          bool vis[110];
          ms(vis,0);
          int flag = false, in = false;
          int cnt = 0;
          for(int i= 1;i <= n;i++ ) {
                if(height[i] >= mid){
                            if(vis[id[sa[i]]] ==0 ) {
                                  vis[id[sa[i]]] = 1;
                                  cnt ++;
                            }
                            if(cnt > k/2 ) {
                                  flag=1;
                                  if(!in) {
                                        in = true;
                                        Pi[mid].pb(sa[i]);
                                  }
                            }
                }else {
                      ms(vis,0);
                      vis[id[sa[i]]] = 1;
                      cnt=1;
                      in = false;
                }
          }
          return flag;
    }
    
    char str[N];
    int main()
    {
          //freopen("in.txt","r",stdin);
          int k;
          int cs = 0;
          while(scanf("%d",&k)==1){
                if(k==0) break;
                int p = 0;
                ms(id,0);
                for(int i =0; i< k;i ++) {
                      scanf("%s",str);
                      for(int j= 0; str[j] ; j ++ , p ++ ) {
                            r[p] = str[j] - 'a' + 1;
                            id[p] = i+1;
                      }
                      r[p++] =27+i;
                }
                p--;
                r[p] = 0;
                da(r,sa,p+1,130);
                calheight(r,sa,p);
                /*
                for(int i=0;i<=p;i++) printf("%d ",sa[i]);
                printf("\n");
                for(int i=0;i<=p;i++) printf("%d ",height[i]);
                      */
                int low= 0, high = p-1, ans = 0,mid;
                while(low <= high) {
                      mid = (low+ high) /2;
                      if(can(mid,p,0,k)) {
                            ans = mid;
                            low = mid+1;
                      }else high = mid-1;
    
    
                }
                if(cs) printf("\n");
                if(ans) {
                      for(int i = 0;i < Pi[ans].size(); i ++ ) {
                            int pivot = Pi[ans][i];
                            for(int j = 0;j < ans; j ++) printf("%c",r[j+pivot] -1 + 'a');
                            printf("\n");
                      }
                }else printf("?\n");
                cs = 1;
                for(int i= 0;i<=p;i++) Pi[i].clear();
          }
          return 0;
    }
    
    

    Suffix-array

    Suffix-array is an important data structure for string.
    Details of suffix array can be found in This link

    Binary Search becomes helpful in this kind of problem.

    Problem Link : POJ 3261

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: POJ - 3261
     Date: 2016-01-16
    
     **************************
    
     */
    #include<vector>
    #include<list>
    #include<deque>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<ctime>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    
    const int N = 2e4+4;
    int wa[N],wb[N],wv[N],wc[N];
    int r[N],sa[N],rak[N], height[N];
    
    // compare of two suffix starting at a & b and gap = l
    int cmp(int *r,int a,int b,int l)
    {
          return r[a] == r[b] && r[a+l] == r[b+l];
    }
    void da(int *r,int *sa,int n,int m)
    {
          int i,j,p,*x=wa,*y=wb,*t;
          for( i=0;i<m;i++) wc[i]=0;
          for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
          for( i=1;i<m;i++) wc[i] += wc[i-1];
          for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
          for( j= 1,p=1;p<n;j*=2,m=p){
                for(p=0,i=n-j;i<n;i++)y[p++] = i;
                for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
                for(i=0;i<n;i++)wv[i] = x[y[i]];
                for(i=0;i<m;i++) wc[i] = 0;
                for(i=0;i<n;i++) wc[wv[i]] ++;
                for(i=1;i<m;i++) wc[i] += wc[i-1];
                for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
                for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
    
          }
    }
    
    void calheight(int *r,int *sa,int n)
    { // height[i] = longest common prefix of (Suffix (sa[i]) & Suffix(sa[i-1]) 
          int i,j,k=0;
          for(i=1;i<=n;i++) rak[sa[i]] = i;
          for(i=0;i<n; i++  ) {
                if(k) k--;
                j = sa[rak[i] - 1];
                while(r[i+k] == r[j+k]) k++;
                height[rak[i]] = k;
          }
    }
    
    bool can(int mid,int n,int k )
    {
          int cnt=1;
          for(int i=2;i<=n;i++){
                if(height[i] < mid) cnt=1;
                else cnt ++;
                if(cnt >= k) return 1;
          }
          return 0;
    }
    
    int a[N];
    int main()
    {
          //freopen("in.txt","r",stdin);
          Dii(n,k);
          int cnt = 0;
          forn(i,n){
                Si(a[i]);
                r[i] = a[i] + 1;
                cnt = max(cnt,r[i]);
          }
          r[n] = 0;
          da(r,sa,n+1,cnt+1);
          calheight(r,sa,n);
          int low= 1,high = n, ans=0,mid;
          while(low <= high) {
                mid = (low + high) / 2;
                if(can(mid,n,k)) {
                      ans = mid;
                      low=  mid+1;
                }else high = mid-1;
          }
          printf("%d\n", ans);
    
    
          return 0;
    }
    
    

    LOJ 1279 – GRAPH COLORING

    Category : Gaussian Elimination

    Solution : k ^ (n- rank) % MOD;

    
    /*
    
     *************************
     Id  : Matrix.code
     Task: 1279 – GRAPH COLORING
     Date: 2016-01-13
    
     **************************
    
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define SZ(a)                   (int) a.size()
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
    Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
    Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
    void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 1000;
    typedef Long T;
    typedef vector<Long> VT;
    typedef vector<VT> VVT;
    
    void show(VVT &a)
    {
          printf("PRINTING\n");
          for(int i = 0; i < SZ(a); i++)
          {
                for(int j = 0; j < SZ(a[0]); j ++ ) printf("%4d",a[i][j]);
                printf("\n");
    
          }
    
    }
    
    int gauss(VVT &a,Long k )
    {
          int n= SZ(a) , m= SZ(a[0]) , r = 0;
          for(int c = 0 ; c < m-1 && r < n ; c ++ ) {
                int j = r;
                for(int i= j+1; i < n; i ++) if(a[i][c]) { j = i; break; }
                if(a[j][c] == 0 ) continue;
                swap(a[j],a[r]);
                T s = modinverse(a[r][c], k);
                for(int i = 0; i < m ; i++ ) a[r][i] = (a[r][i] * s) % k;
                for(int i = 0; i < n ; i ++ ) if(i!=r) {
                      if(a[i][c] == 0) continue;
                      Long t = a[i][c];
                      for(int j= 0; j < m; j ++ ) a[i][j] = ((a[i][j] - t * a[r][j]) % k + k ) % k;
                }
                r++;
                //show(a);
          }
          return r;
    }
    vector<int> G[N];
    int main()
    {
    
          //freopen("in.txt","r",stdin);
    
          Di(t);
          int cs = 0;
          while(t--) {
                Long n,m,k;
                scanf("%lld %lld %lld",&n,&m,&k);
                forn(i,m) {
                      Dii(a,b);
                      a--,b--;
                      G[a].pb(b);
                      G[b].pb(a);
                }
                VVT a(n,VT(n+1,0));
                for(int i =0 ;i < n ; i ++ ) {
                      a[i][i] = 1;
                      for(int j = 0; j < SZ(G[i]) ;j  ++) {
                            a[i][G[i][j]] = k-1;
                      }
                      a[i][n] = 0;
                }
                //show(a);
                int r = gauss(a,k);
                printf("Case %d: %lld\n" , ++cs , bigmod(k,n-r,1000000007LL));
                for(int i = 0; i < n; i ++ ) G[i].clear();
          }
          return 0;
    }