Common Substrings POJ - 3415 后缀数组+单调栈

A substring of a string T is defined as:

T( i, k)= TiTi +1... Ti+k -1, 1≤ ii+k-1≤| T|.

Given two strings A, B and one integer K, we define S, a set of triples (i, j, k):

S = {( i, j, k) | kK, A( i, k)= B( j, k)}.

You are to give the value of |S| for specific A, B and K.

Input

The input file contains several blocks of data. For each block, the first line contains one integer K, followed by two lines containing strings A and B, respectively. The input file is ended by K=0.

1 ≤ |A|, |B| ≤ 105
1 ≤ Kmin{|A|, |B|}
Characters of A and B are all Latin letters.

Output

For each case, output an integer |S|.

Sample Input
2
aababaa
abaabaa
1
xx
xx
0
Sample Output
22
5

其实这个题目还真的不好说明白,但是这个题目理解了之后更能理解查询任意后缀的最大公共前缀是多少这种问题,因为他具有传递性质,直接看代码会比看解释来的轻松
 
   
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=1e6+10;
char s[MAXN],s1[MAXN];
int t1[MAXN],t2[MAXN],cc[MAXN],x[MAXN],sa[MAXN],Rank[MAXN],height[MAXN],kk,stk[MAXN],top,cnt[MAXN];
int len;
bool cmp(int *y,int a,int b,int k)
{
    int a1=y[a];
    int b1=y[b];
    int a2=a+k>=len ? -1:y[a+k];
    int b2=b+k>=len ? -1:y[b+k];
    return a1==b1 && a2==b2;
}
void make_sa()
{
    int *x=t1,*y=t2;
    int m=300;
    for(int i=0; i=0; i--) sa[--cc[x[i]]]=i;
    for(int k=1; k<=len; k<<=1)
    {
        int p=0;
        for(int i=len-k; i=k ) y[p++]=sa[i]-k;

        for(int i=0; i=0; i--) sa[--cc[x[y[i]]]]=y[i];
        swap(x,y);
        m=1;
        x[sa[0]]=0;
        for(int i=1; i=len ) break;
    }
}
void make_height()
{
    for(int i=0; iheight[i])
            {
                sum-=(long long)((stk[top]-kk+1)*cnt[top]);
                sum+=(long long)((height[i]-kk+1)*cnt[top]);
                num+=cnt[top--];
            }
            stk[++top]=height[i];
            if(sa[i-1]>len1)
            {
                sum+=(long long)(height[i]-kk+1);
                cnt[top]=num+1;
            }
            else cnt[top]=num;
            if(sa[i]height[i])
            {
                  sum-=(long long)((stk[top]-kk+1)*cnt[top]);
                sum+=(long long)((height[i]-kk+1)*cnt[top]);
                num+=cnt[top--];
            }
            stk[++top]=height[i];
            if(sa[i-1]len1)
                ans+=sum;
        }
        printf("%lld\n",ans);
    }


}

 

你可能感兴趣的:(后缀数组)