spoj 694は1つの文字列の中で異なっているサブストリングの個数を求めます.


SPOJ Problem Set 694.Dispinct Substrigs Problem code:DISUBSTR
Given a string、we need to find the total number of its distinct substrigs.
Input
T-number of test cases.T<=20;Each test case consists of one string、whose length is<=1000
Output
For each test case output one number saying the number of distinct substrigs.
Example
Sample Input:2 CCC ABA
Sample Output:5
Explanion for the testcase with string ABA:  len=1:A、B len=2:AB、BA len=3:ABA、BAB len=4:ABAB、BABA len=5:ABABA B ABABA Thus、total number of distinct substrigs 9.
1、プレフィックスで別のサブストリングを見ます.--長さiの文字列は全部でiのプレフィックスがあります.
2、各サブストリングはいずれも接頭辞であり、問題はすべての異なる接頭辞の個数を求めることに等しい.
その後、sa[1]を押して、sa[2]…順に接尾辞観察を加えます.suffix長さはn-sa[i]で、全部でn-sa[i]個の接頭辞があり、lcp[i-1](前の接頭辞の最長共通接頭辞の長さです.)を引いて、新たに加わった新しい接頭辞の個数です.
最後に和を求めればいいです
注意私のlcp[i]とは、スフィクス(sa[i])とスフィクス(sa[i+1])の共通プレフィックスの長さを意味します.
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define MAXN 1011

int n,k;//n=strlen(s);

int Rank[MAXN];
int tmp[MAXN];
char s[MAXN];
int lcp[MAXN],sa[MAXN];

/*  Rank sa  */
bool cmpSa(int i, int j)
{
    if(Rank[i] != Rank[j])return Rank[i] < Rank[j];
    else
    {   /*   Rank[t],    t        k/2 ,
        sa[i]   ,   i     ,     */
        int ri = i+k <=n? Rank[i+k]:-1;
        int rj = j+k <= n ? Rank[j+k]:-1;
        return ri 0)h--;
        for(; j+h