关于后缀数组的奇怪问题
查看原帖
关于后缀数组的奇怪问题
259909
zhaluo楼主2021/2/18 16:32

求后缀数组,枚举后k个关键字时,如果倒序枚举我就能ac,正序枚举就wa

for (int i = n-k+1; i <= n ; i++) y[++num]=i;//wa
for (int i = n; i >= n-k+1 ; i--) y[++num]=i;//ac

完整代码

#include <bits/stdc++.h>

using namespace std;

const int maxn=500000;
long long sa[maxn],rk[maxn],height[maxn];
int c[maxn],x[maxn],y[maxn];

void get_sa(string str){
    int n=str.length(),m=123;
    str='\0'+str;
    for (int i = 0; i <= m; i++) c[i]=0;
    for (int i = 1; i <= n; i++) c[x[i]=str[i]]++;
    for (int i = 2; i <= m; i++) c[i]+=c[i-1];
    for (int i = n; i ; i--) sa[c[x[i]]--]=i;
    for (int k = 1; k < n; k<<=1)
    {
        int num=0;
        ///////////////////////////
        //for (int i = n-k+1; i <= n ; i++) y[++num]=i;
        for (int i = n; i >= n-k+1 ; i--) y[++num]=i;
        ///////////////////////////
        for (int i = 1; i <= n; i++) if(sa[i]>k) y[++num]=sa[i]-k;
        for (int i = 0; i <= m; i++) c[i]=0;
        for (int i = 1; i <= n; i++) c[x[i]]++;
        for (int i = 2; i <= m; i++) c[i]+=c[i-1];
        for (int i = n; i ; i--) sa[c[x[y[i]]]--]=y[i];
        memcpy(y,x,sizeof(x));
        num=1;
        x[sa[1]]=1;
        for (int i = 2; i <= n; i++)
        {
            if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])
                x[sa[i]]=num;
            else x[sa[i]]=++num;
        }
        if(num==n) break;
        m=num;
    }  
    for (int i = 1; i <= n; i++)
    {
        rk[sa[i]]=i;
    }
}

void get_height(string str){
    int k=0,n=str.length();
    str='\0'+str;
    for(int i=1;i<=n;i++){
        if(rk[i]==1) continue;
        if(k) k--;
        int j=sa[rk[i]-1],l=max(i,j);
        while(l+k<=n&&str[j+k]==str[i+k])
            k++;
        height[rk[i]]=k;

    }
    //return ans;
}

long long cal(string str){
    int l=str.length(),top;
    long long ans=0;
    long long stk[l+1],L[l+1],R[l+1];
    get_sa(str);
    get_height(str);
    str='\0'+str;
    stk[top=0]=1;
    for (int i = 2; i <= l; i++)
    {
        while (top && height[stk[top]]>=height[i]) 
            top--;
        L[i]=stk[top];
        stk[++top]=i;
    }
    stk[top=0]=l+1;
    for (int i = l; i >= 2 ; i--)
    {
        while (top && height[stk[top]]>height[i]) top--;
        R[i]=stk[top];
        stk[++top]=i;
    }
    for (int i = 2; i <= l; i++)
    {
        ans=ans+(height[i])*(R[i]-i)*(i-L[i]);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    string str1,str2,str;
    cin>>str1>>str2;
    str=str1+' '+str2;
    long long ans=cal(str);
    ans-=cal(str1);
    ans-=cal(str2);
    cout<<ans;
    return 0;
}
/*
aacb
bcaa
*/
2021/2/18 16:32
加载中...