hdu 6599 (palindrome tree)

Portal

Meaning of the questions:

To give you a length \ (n-\) string length is now ask you \ (1,2 \ dots n \) of the substring, the number of substrings \ (STR \) is a palindromic sequence, and it to shorten the length of $ \ lceil \ frac {| str |} {2} \ $ rceil the palindromic sequence also.

analysis:

Obviously, we can use the tree are palindromic \ (CNT \) arrays and \ (Fail \) array, an arbitrary length of the \ (len \) palindromic substrings and its longest string suffix palindromic \ (\ mathcal {O} ( n) \) time out process. Know how to find things after the above, we only need to consider how to eliminate some of the illegal palindrome substring.

For a palindromic sequence \ (STR \) , he wants him corresponds to the first half palindrome half palindrome, the palindrome then if his longest suffix length less than \ (\ frac {| str | } {2 } \) , it is clearly not, therefore be considered equal to a length greater than the longest palindromic suffix \ (\ frac {|} { 2} \) | str case. We found that if you want it after half palindrome, it is to shorten delete a number of original series and the longest palindrome suffix poor, so we only need to determine $ \ lfloor \ frac {| str |} {2} \ rfloor $ whether divisible \ ((| str | - | str_ {maxsuffix} |) \) to

Code:

#include <bits/stdc++.h>
#define maxn 300005
using namespace std;
char str[maxn];
typedef long long ll;
struct PAM{//回文树
    int next[maxn][26],fail[maxn],len[maxn],cnt[maxn],S[maxn];
    int id,n,last;
    int newnode(int x){
        for(int i=0;i<26;i++){
            next[id][i]=0;
        }
        cnt[id]=0;
        len[id]=x;
        return id++;
    }
    void init(){
        id=0;
        newnode(0);
        newnode(-1);
        fail[0]=1;
        S[0]=-1;
        last=n=0;
    }
    int getfail(int x){
        while(S[n-len[x]-1]!=S[n]) x=fail[x];
        return x;
    }
    void Insert(int c){
        c-='a';
        S[++n]=c;
        int cur=getfail(last);
        if(!next[cur][c]){
            int now=newnode(len[cur]+2);
            fail[now]=next[getfail(fail[cur])][c];
            next[cur][c]=now;
        }
        last=next[cur][c];
        cnt[last]++;
    }
    void getsum(){//自下向上更新
        for(int i=id-1;i>=0;i--){
            cnt[fail[i]]+=cnt[i];
        }
    }
}pam;
int Ans[maxn];
bool judge(int x,int Len){
    int tmp1=pam.len[pam.fail[x]];
    int tmp2=pam.len[x]-tmp1;
    if((pam.len[x]/2)%tmp2==0) return true;
    else return false;
}
int main()
{
    while(~scanf("%s",str)){
        pam.init();
        int len=strlen(str);
        for(int i=0;i<=len;i++){
            Ans[i]=0;
        }
        for(int i=0;i<len;i++){
            pam.Insert(str[i]);
        }
        pam.getsum();
        ll res=0;
        for(int i=2;i<pam.id;i++){
            if(judge(i,(pam.len[i]+1)/2)){
                Ans[pam.len[i]]+=pam.cnt[i];
            }
        }
        for(int i=1;i<=len;i++){
            if(i==1) printf("%d",Ans[i]);
            else printf(" %d",Ans[i]);
        }
        puts("");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Chen-Jr/p/11240112.html