Equivalent Suffix Tries

All submissions for this problem are available.
Suffix trees are very powerful data structures. Using suffix trees it's often easy to solve the hardest computer science problems on strings. In this problem we'll consider a simplified version of suffix trees -- suffix tries (that is, tries formed by all suffixes of a given string).
Generally, the suffix tree is a tree whose edges are labeled with strings. Instead, we'll only consider suffix tries whose edges are labeled with single characters. This way every edge of a suffix tree may correspond to one or more edges connected in a chain-style fashion of a suffix trie.
Another trait of suffix trees is that each suffix of the string for which the suffix tree is built corresponds to exactly one path from the tree's root to a leaf. This is usually achieved by terminating each suffix of the string with a special character, say, $. However, in suffix tries we won't do that. In particular, this implies that the number of leaves in a suffix trie can be smaller than the length of the original string.
In the picture the suffix tries for strings 'aba' and 'abac' are presented:

If we erase all letters from the edges of a suffix trie, it actually becomes a directed graph. Let's call two suffix tries equivalent if their corresponding directed graphs are isomorphic.
You're given a single string consisting of lowercase Latin letters. Your task is to find the number of different strings of the same length consisting of lowercase Latin letters as well such that their suffix tries are equivalent to the suffix trie of the given string. As this number can be large enough, output the remainder of its division by 42424242.
Input
The first line contains a single number T -- the number of test cases (no more than 10). Each of the next T lines contains a single non-empty string of length no more than 100000 consisting of lowercase Latin letters a..z.
Output
For each test case output just one line containing the sought number modulo 42424242.
Example

Input:
5
a
aa
abc
aba
helloworld

Output:
26
26
15600
1300
6221124

Explanation:

In the first test case every string of length 1 satisfies the condition. In the second test case every string consisting of two equal letters is fine. In the third test case every string comprising three pairwise distinct letters adds 1 to the answer. In the fourth test case string 'bee' is one of the 1300 good strings.

Example input:

Example output:


Solution:

    #include<algorithm>
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include  <stdio.h>
    #include   <math.h>
    #include   <time.h>
    #include   <vector>
    #include    <queue>
    #include      <map>
    #include      <set>
    using namespace std;
    
    const int N=100005;
    
    typedef unsigned long long ULL;
    
    vector<ULL> Ansset;
    
    int n,m,lcp[N],next[N];
    
    char str[N];
    
    ULL H[N],P[N];
    
    inline ULL Hash(int l,int r)
    {
    	return H[r]-H[l-1]*P[r-l+1];
    }
    
    inline int Lcp(int x,int y)
    {
    	if(x>y)
    		swap(x,y);
    	int l=1,r=n-y+1,lcp=0;
    	while(l<=r)
    	{
    		int Mid=l+r>>1;
    		if(Hash(x,x+Mid-1)==Hash(y,y+Mid-1))
    			lcp=Mid,l=Mid+1;
    		else
    			r=Mid-1;
    	}
    	return lcp;
    }
    
    inline ULL GetHash(int i,int len)
    {
    	ULL Now=0;
    	while(len>0)
    	{
    		int L=min(n-i+1-m,len);Now=Now*P[L]+Hash(i,i+L-1);len-=L;
    	}
    	return Now;
    }
    
    void solve()
    {
    	scanf("%s",str+1);n=strlen(str+1);
    	bool ok[26]={},vis[26]={};
    	for(int i=1;i<=n;i++)
    		H[i]=H[i-1]*233+str[i];
    	reverse(str+1,str+n+1);next[0]=-1;m=0;
    	for(int i=1;i<=n;i++)
    	{
    		int k=next[i-1];
    		while(k!=-1&&str[k+1]!=str[i])
    			k=next[k];
    		m=max(m,next[i]=k+1);vis[str[i]-'a']=1;
    	}
    	reverse(str+1,str+n+1);
    	int Max=1;
    	for(int i=1;i<n-m;i++)
    		Max=max(Max,lcp[i]=Lcp(i,n-m));
    	for(int i=1;i<n-m;i++)
    		if(Max==lcp[i])
    			ok[str[i+Max]-'a']=1;
    	Ansset.clear();
    	for(int i=1;i<=n-m;i++)
    		if(Hash(n-m+1,n-m+Max-1)==GetHash(i,Max-1)&&!ok[str[i+(Max-1)%(n-m-i+1)]-'a'])
    			Ansset.push_back(GetHash(i,m));
    	sort(Ansset.begin(),Ansset.end());Ansset.erase(unique(Ansset.begin(),Ansset.end()),Ansset.end());
    	int Ans=Ansset.size(),Num=26;
    	for(int i=0;i<26;i++)
    		if(vis[i])
    			Ans=Ans*Num%42424242,Num--;
    	printf("%d\n",Ans);
    }
    
    int main()
    {
    	P[0]=1;
    	for(int i=1;i<N;i++)
    		P[i]=P[i-1]*233;
    	int t;cin>>t;
    	while(t--)
    		solve();
    	return 0;
    }