后缀数组 专题

国家队论文链接:链接:http://pan.baidu.com/s/1E1K4m 密码:cfog

(更新中)

/***********************************************************/

简单的说,后缀数组是“排第几的是谁?”,名次数组是“你排第几?”。

待排序的字符串放在r 数组中,从r[0]到r[n-1],长度为n,且最大值小
于m。为了函数操作的方便,约定除r[n-1]外所有的r[i]都大于0, r[n-1]=0。
函数结束后,结果放在sa 数组中,从sa[0]到sa[n-1]。

height 数组:定义height[i]=suffix(sa[i-1])和suffix(sa[i])的最长公
共前缀,也就是排名相邻的两个后缀的最长公共前缀。

/***********************************************************/

poj 1743 Musical Theme http://poj.org/problem?id=1743 不可重叠重复字串

/**************************************************************
    Problem:poj 1743
    User: youmi
    Language: C++
    Result: Accepted
    Time:219MS
    Memory:1384K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <ctime>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d
",a)
#define ptlld(a) printf("%I64d
",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
const int maxn=20010;

int wa[maxn],wb[maxn],wv[maxn],cnt[maxn];
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++) cnt[i]=0;
     for(i=0;i<n;i++) cnt[x[i]=r[i]]++;
     for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
     for(i=n-1;i>=0;i--) sa[--cnt[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++) cnt[i]=0;
       for(i=0;i<n;i++) cnt[wv[i]]++;
       for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
       for(i=n-1;i>=0;i--) sa[--cnt[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++;
     }
     return;
}
int rk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
     int i,j,k=0;
     for(i=1;i<=n;i++) rk[sa[i]]=i;
     for(i=0;i<n;height[rk[i++]]=k)
     for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     return;
}
int r[maxn],sa[maxn];
int f[maxn];
int n;
bool work(int temp)
{
    int l=oo,r=-1;
    for(int i=2;i<=n;i++)
    {
        while(height[i]>=temp)
        {
            l=Min(l,Min(sa[i],sa[i-1]));
            r=Max(r,Max(sa[i],sa[i-1]));
            i++;
        }
        if(r-l>=temp)
            return true;
        else
        {
            l=oo,r=-1;
        }
    }
    return false;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~sc(n)&&n)
    {
        rep0(i,n)
            sc(f[i]);
        for(int i=0;i<n-1;i++)
            r[i]=f[i+1]-f[i]+88;
        n--;
        r[n]=0;
        /**< for(int i=0;i<=n;i++)
            printf("%d ",r[i]);
        cout<<endl; */
        da(r,sa,n+1,200);
        calheight(r,sa,n);
        int l=0,r=n+1;
        int mid=0;
        int ans=0;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(work(mid))
            {
                l=mid+1;
                ans=mid;
            }
            else
                r=mid-1;
        }
        if(ans>=4)
        {
            pt(ans+1);
        }
        else
            printf("0
");
    }
    return 0;
}
View Code

poj 3261 Milk Patterns http://poj.org/problem?id=3261  可重叠重复字串K次

/**************************************************************
    Problem:poj 3261
    User: youmi
    Language: C++
    Result: Accepted
    Time:32MS
    Memory:1480K
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <ctime>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d
",a)
#define ptlld(a) printf("%I64d
",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
const int maxn=20010;

int wa[maxn],wb[maxn],wv[maxn],cnt[maxn];
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++) cnt[i]=0;
     for(i=0;i<n;i++) cnt[x[i]=r[i]]++;
     for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
     for(i=n-1;i>=0;i--) sa[--cnt[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++) cnt[i]=0;
       for(i=0;i<n;i++) cnt[wv[i]]++;
       for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
       for(i=n-1;i>=0;i--) sa[--cnt[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++;
     }
     return;
}
int rk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
     int i,j,k=0;
     for(i=1;i<=n;i++) rk[sa[i]]=i;
     for(i=0;i<n;height[rk[i++]]=k)
     for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     return;
}
int r[maxn],sa[maxn];
typedef struct
{
    int v,p;
}node;
node ha[maxn];
bool small(const node a,const node b)
{
    if(a.v==b.v)
        return a.p<b.p;
    return a.v<b.v;
}
int n,k;
void to_one()
{
    sort(ha,ha+n,small);
    int cnt=1;
    r[ha[0].p]=cnt;
    for(int i=1;i<n;i++)
    {
        if(ha[i].v!=ha[i-1].v)
            r[ha[i].p]=++cnt;
        else
            r[ha[i].p]=r[ha[i-1].p];
    }
}
bool work(int temp)
{
    int tot;
    for(int i=2;i<=n;i++)
    {
        tot=1;
        while(height[i]>=temp)
        {
            tot++;
            i++;
        }
        if(tot>=k)
            return true;
    }
    return false;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~sc2(n,k))
    {
        rep0(i,n)
        {
            sc(ha[i].v);
            ha[i].p=i;
        }
        to_one();
        r[n]=0;
         /**<for(int i=0;i<=n;i++)
            printf("%d ",r[i]);
        cout<<endl; */
        da(r,sa,n+1,n+1);
        calheight(r,sa,n);
        int l=0,r=n+1;
        int mid=0;
        int ans=0;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(work(mid))
            {
                l=mid+1;
                ans=mid;
            }
            else
                r=mid-1;
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code

ural 1297 回文串 http://acm.timus.ru/problem.aspx?space=1&num=1297

/**************************************************************
    Problem:ural 1297
    User: youmi
    Language: C++
    Result: Accepted
    Time:0.015    s
    Memory:568 KB
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d
",a)
#define ptlld(a) printf("%I64d
",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;

const int maxn=2010;

int wa[maxn],wb[maxn],wv[maxn],cnt[maxn];
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++) cnt[i]=0;
     for(i=0;i<n;i++) cnt[x[i]=r[i]]++;
     for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
     for(i=n-1;i>=0;i--) sa[--cnt[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++) cnt[i]=0;
       for(i=0;i<n;i++) cnt[wv[i]]++;
       for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
       for(i=n-1;i>=0;i--) sa[--cnt[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++;
     }
     return;
}
int rk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
     int i,j,k=0;
     for(i=1;i<=n;i++) rk[sa[i]]=i;
     for(i=0;i<n;height[rk[i++]]=k)
     for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     return;
}

int r[maxn],sa[maxn];
char s[maxn];
int n;
int dp[maxn][15];
void  test()
{
    rep1(i,n)
        printf("%d ",dp[i][0]);
    cout<<endl;
}
void RMQ()
{
    int k=(int)(log(n*1.0)/log(2.0));
    for(int i=1;i<=n;i++)
        dp[i][0]=height[i];
    for(int j=1;j<=k;j++)
        for(int i=1;i+(1<<j)<=n;i++)
            dp[i][j]=Min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int lcp(int a,int b)
{
    int l=rk[a],r=rk[b];
    if(l>r)
    {
        int t=l;
        l=r;
        r=t;
    }
    l++;
    int k=(int )(log((r-l+1)*1.0)/log(2.0));
    return Min(dp[l][k],dp[r-(1<<(k))+1][k]);
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scs(s))
    {
        int len=strlen(s);
        n=0;
        for(int i=0;i<len;i++)
            r[n++]=s[i];
        r[n++]=150;
        for(int i=0;i<len;i++)
            r[n++]=s[len-i-1];
        r[n]=0;
        da(r,sa,n+1,160);
        calheight(r,sa,n);
        RMQ();
        int pos=0,ans=1;
        int temp=0;
        int m=(len<<1);
        for(int i=0;i<len;i++)
        {
            temp=(lcp(i,m-i)<<1)-1;
            if(temp>ans)
                ans=temp,pos=i-(temp>>1);
            temp=lcp(i,(m-i+1))<<1;
            if(temp>ans)
                ans=temp,pos=i-(temp>>1);
        }
        for(int i=pos;i<pos+ans;i++)
            printf("%c",s[i]);
        cout<<endl;
    }
    return 0;
}
View Code

poj 1226 Substrings http://poj.org/problem?id=1226

/**************************************************************
    Problem:poj 1226
    User: youmi
    Language: C++
    Result: Accepted
    Time:0MS
    Memory:1056K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d
",a)
#define ptlld(a) printf("%I64d
",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;

const int maxn=200100;
int wa[maxn],wb[maxn],wv[maxn],cnt[maxn];
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++) cnt[i]=0;
     for(i=0;i<n;i++) cnt[x[i]=r[i]]++;
     for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
     for(i=n-1;i>=0;i--) sa[--cnt[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++) cnt[i]=0;
       for(i=0;i<n;i++) cnt[wv[i]]++;
       for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
       for(i=n-1;i>=0;i--) sa[--cnt[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++;
     }
     return;
}
int rk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
     int i,j,k=0;
     for(i=1;i<=n;i++) rk[sa[i]]=i;
     for(i=0;i<n;height[rk[i++]]=k)
     for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     return;
}
char str[maxn];
int r[maxn],sa[maxn];
int who[maxn];
int vis[500];
int n,m;
bool check(int temp)
{
    int tot=0;
    zeros(vis);
    for(int i=2;i<=n;i++)
    {
        if(height[i]<temp)
        {
            tot=0;
            zeros(vis);
        }
        else
        {
            if(!vis[who[sa[i]]])
            {
                vis[who[sa[i]]]=1;
                tot++;
            }
            if(!vis[who[sa[i-1]]])
            {
                vis[who[sa[i-1]]]=1;
                tot++;
            }
            if(tot==m)
                return true;
        }
    }
    return false;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        n=0;
        int sp=150;
        sc(m);
        rep1(i,m)
        {
            scs(str);
            int s1=strlen(str);
            for(int j=0;str[j];j++)
            {
                who[n]=i;
                r[n++]=str[j];
            }
            who[n]=sp;
            r[n++]=sp++;
            for(int j=0;str[j];j++)
            {
                who[n]=i;
                r[n++]=str[s1-j-1];
            }
            who[n]=sp;
            r[n++]=sp++;
        }
        r[n]=0;
        da(r,sa,n+1,sp);
        calheight(r,sa,n);
        int l=0,r=strlen(str);
        int mid=0,ans=0;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid))
            {
                l=mid+1;
                ans=mid;
            }
            else
                r=mid-1;
        }
        pt(ans);
    }
    return 0;
}
View Code

hdu 5769 substring 

题意:给一个字符,下面一个串,问你下面的串可以组成的子串中有多少个包含这个字符的

思路:(自己没想出来,看别人博客会的,传送门,为了方便,我把思路也copy过来吧,写的挺好的)我们将sa[i]代表的串里有这个字符的全部标记起来,只有这些才会对我们的结果有贡献值,然后正常的我们算不重复子串的个数是len-sa[i]-height[i],但是现在有这样的情况,就是字符是c,而sa[i]是dddcddd,那么它能贡献的值就是len-max((sa[i]+height[i]),c的位置),因为若sa[i]+height[i]的值大于c的位置,这与正常的没有区别,但是若c的位置大于sa[i]+height[i],那么这个sa能贡献的就只有c位置和之后的串,所遇这里取个最大值就行了 

/**************************************************************
    Problem:hdu 5769 Substring
    User: youmi
    Language: C++
    Result: Accepted
    Time:140MS
    Memory:5160K
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <ctime>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d
",a)
#define ptlld(a) printf("%I64d
",a)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
const int maxn=100100;

int wa[maxn],wb[maxn],wv[maxn],cnt[maxn];
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++) cnt[i]=0;
     for(i=0;i<n;i++) cnt[x[i]=r[i]]++;
     for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
     for(i=n-1;i>=0;i--) sa[--cnt[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++) cnt[i]=0;
       for(i=0;i<n;i++) cnt[wv[i]]++;
       for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
       for(i=n-1;i>=0;i--) sa[--cnt[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++;
     }
     return;
}
int rk[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
     int i,j,k=0;
     for(i=1;i<=n;i++) rk[sa[i]]=i;
     for(i=0;i<n;height[rk[i++]]=k)
     for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     return;
}
int r[maxn],sa[maxn];
char s[maxn],ch[10];
int n;
int op[maxn];
int main()
{
    #ifndef ONLINE_JUDGE
        //freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int T_T;
    sc(T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        printf("Case #%d: ",kase);
        scanf("%s%s",ch,s);
        n=strlen(s);
        int st=n;
        for(int i=n-1;i>=0;i--)
        {
            r[i]=s[i];
            if(s[i]==ch[0])
                st=i;
            op[i]=st;
        }
        r[n]=0;
        da(r,sa,n+1,128);
        calheight(r,sa,n);
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            ans+=n-Max(sa[i]+height[i],op[sa[i]]);
        }
        ptlld(ans);
    }
    return 0;
}
View Code
不为失败找借口,只为成功找方法
原文地址:https://www.cnblogs.com/youmi/p/4826111.html