HDU3948:后缀数组+马拉车(本质不同回文子串统计)

题意:给出一个字符串,求其 本质不同的 回文子串的个数。


如果有小伙伴WA了无数次,请尝试模拟一下aabaa这个串,答案应该是5。(本菜鸡就WA了一晚上)


题解:回文子串可以考虑先来个O(n)的马拉车预处理,这样每个回文子串长度必然是计数,那么我们可以统计本质不同的(正中间的字符+右半边串)回文子串个数。然后可以考虑用后缀自动机统计答案。这道题的关键的关键在于去重的处理。去重要求去掉:h[i]范围内已经被统计过的串。那么可以用一个变量维护 目前已经被统计过的长度。要注意到h数组和马拉车的lc数组是没什么关系的。


Code:

#include
using namespace std;
#define rank rk
const int MAX = 2e5+10000;
char ch[MAX];
int cntA[MAX],cntB[MAX],A[MAX],B[MAX],tsa[MAX],rank[MAX],SA[MAX],lc[MAX],h[MAX];
int n,t;
int Cas =1; 
void init(){
    memset(ch,0,sizeof ch);
    ch[0]='z'+1;
}
void input(){
    scanf("%s",ch+1);
    n =  strlen(ch+1);
    ch[n*2+1]='#';
    for (int i=n;i>=1;i--){
        ch[i*2] = ch[i];
        ch[i*2-1] ='#';
    }
    n = n*2+1;
    ch[n+1]='\0';
}
void get_SA(){
    for (int i=0;i<=10000;i++) cntA[i]=0;
    for (int i=1;i<=n;i++) cntA[ch[i]]++;
    for (int i=1;i<=10000;i++) cntA[i]+=cntA[i-1];
    for (int i=n;i>=1;i--) SA[cntA[ch[i]]--] =i;
    rank[SA[1]]=1;
    for (int i=2;i<=n;i++){
        rank[SA[i]]=rank[SA[i-1]];
        if (ch[SA[i]]!=ch[SA[i-1]]) rank[SA[i]]++;
    }
    for (int step = 1;rank[SA[n]]=1;i--) tsa[cntB[B[i]]--] =i;
        for (int i=n;i>=1;i--) SA[cntA[A[tsa[i]]]--] = tsa[i];
        rank[SA[1]]=1;
        for (int i=2;i<=n;i++){
            rank[SA[i]]=rank[SA[i-1]];
            if (A[SA[i]]!=A[SA[i-1]]||B[SA[i]]!=B[SA[i-1]]) rank[SA[i]]++;
        }
    }
}
void get_Height(){
    for (int i=1,j=0;i<=n;i++){
        if (j) j--;
        while (ch[i+j]==ch[SA[rank[i]-1]+j])j++;
        h[rank[i]]=j;
    }
}
void Manacher(){
    lc[1]=1;
    int k=1;
    for (int i=2;i<=n;i++){
//        printf("%d %d\n",i,k);
        int p = k+lc[k]-1;
        if (i<=p){
            lc[i]=min(lc[2*k-i],p-i+1);
        }else{
            lc[i]=1;
        }
        while (ch[i+lc[i]]==ch[i-lc[i]])lc[i]++;
        if (i+lc[i]>k+lc[k])k=i;
    }
}
void print(){
    printf("%s\n",ch+1);
    for (int i=1;i<=n;i++){
        printf("%s %d\n",ch+SA[i],lc[SA[i]]);
    }
}
void solve(){
    get_SA();
    get_Height();
    Manacher();
    print();
    long long res =0;
//    cout<<"1: "<cnt){
        	cnt = lc[SA[i]];
        }
    }
//    cout<


你可能感兴趣的:(HDU)