This question is how many different substrings with N length appear in a string, and different characters in the parent string are given.
Number of NC.
It is definitely time-out to save the sub-string to the set. This question has a solution using string hash, although theoretically there are
Bug.
Use the given NC to treat the string with a length of N as a numerical number in the NC system, find its value, and hash the value,
Calculate the number of hash locations.
This algorithm is actually similar to the Karp-Rabin string matching algorithm. However, the Karp-Rabin algorithm has been improved.
In order to prevent overflow, a prime number is modeled when the string is evaluated as D, and the next substring is not obtained every iteration.
Instead, the value of the next character is directly delivered from the value of the current substring. It is actually very easy to recursive, that is, to delete the current value.
Remove the highest bit and multiply it by D (equivalent to moving one digit to the left, but instead of using the <symbol), and add the new lowest Bit.
The Karp-Rabin algorithm should mainly be used to design a reasonable hash algorithm. For example, if the modulo hash function is used
The hash table is large enough, otherwise there will be too many conflicts and the speed will not be good. For example, if the hash table is small, the AC will fail.
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
Const int MAX = 13747347;
Int nHash [MAX];
Char szStr [17000001];
Int nN, nNC;
Int nW [200];
Void Insert (int nKey)
{
Int nPos = nKey;
While (nHash [nPos]! =-1 & nHash [nPos]! = NKey)
{
NPos = (nPos + 1) % MAX;
}
NHash [nPos] = nKey;
}
Bool Find (int nKey)
{
Int nPos = nKey;
While (nHash [nPos]! =-1 & nHash [nPos]! = NKey)
{
NPos = (nPos + 1) % MAX;
}
Return nHash [nPos]! =-1;
}
Int main ()
{
While (scanf ("% d % s", & nN, & nNC, szStr) = 3)
{
Memset (nW, 0, sizeof (nW ));
Memset (nHash,-1, sizeof (nHash ));
Int nNum = 0;
Int nSize = 0;
For (char * pszStr = szStr; * pszStr; ++ pszStr)
{
If (! NW [* pszStr])
{
NW [* pszStr] = ++ nNum;
}
++ NSize;
}
Int nKey = 0;
Int nAns = 0;
Int nPowN = 1;
For (int j = 0; j <nN; ++ j)
{
NKey = (nKey * nNC + nW [szStr [j]) % MAX;
NPowN * = nNC;
}
NPowN/= nNC;
If (! Find (nKey ))
{
Insert (nKey );
NAns ++;
}
For (int I = nN; I <nSize; ++ I)
{
NKey = (nNC * (nKey-nPowN * nW [szStr [I-nN])
+ NW [szStr [I]) % MAX;
NKey = (nKey + MAX) % MAX;
If (! Find (nKey ))
{
Insert (nKey );
NAns ++;
}
}
Printf ("% d \ n", nAns );
}
Return 0;
}