牛客多校__string

鏈接:https://ac.nowcoder.com/acm/contest/884/I
 

時間限制:C/C++ 2秒,其他語言4秒
空間限制:C/C++ 524288K,其他語言1048576K
64bit IO Format: %lld

題目描述

We call a,ba,ba,b non-equivalent if and only if a≠ba \neq ba​=b and a≠rev(b)a \neq rev(b)a​=rev(b), where rev(s)rev(s)rev(s) refers to the string obtained by reversing characters of sss, for example rev(abca)=acbarev(abca)=acbarev(abca)=acba.

There is a string sss consisted of lower-case letters. You need to find some substrings of sss so that any two of them are non-equivalent. Find out what's the largest number of substrings you can choose.

輸入描述:

A line containing a string sss of lower-case letters.

輸出描述:

A positive integer - the largest possible number of substrings of sss that are non-equivalent.

示例1

輸入

複製

abac

輸出

複製

8

說明

The set of following substrings is such a choice: abac,b,a,ab,aba,bac,ac,cabac,b,a,ab,aba,bac,ac,cabac,b,a,ab,aba,bac,ac,c.

 

題意:對於給出的一個串,找出本質不同的串,同時這些本質不同的串的反轉串不能和其他的串的原串一樣

題解:在一個後綴自動機上建立原串和反轉串,然後就可以求本質不同的串p,但這樣本身是迴文串的會被算少一次,所以我們需要用迴文輸算出這個串的本質不同的迴文串的數目q,然後(p+q)/2就是答案了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int maxn = 5e5+9;

char s[maxn];
int vis[maxn];

struct SAM{
    int len[maxn<<1],link[maxn<<1],ch[maxn<<1][26];
    int num[maxn<<1];
    int sz,rt,last;
    int newnode(int x=0){
        len[sz]=x;
        link[sz]=-1;
        memset(ch[sz],-1,sizeof(ch[sz]));
        return sz++;
    }
    void init(){sz=last=0,rt=newnode();}
    void reset(){last=0;}
    void extend(int c){
        int np=newnode(len[last]+1);
        int p;
        for(p=last;~p&&ch[p][c]==-1;p=link[p])ch[p][c]=np;
        if(p==-1){
            link[np]=rt;
        }
        else{
            int q=ch[p][c];
            if(len[p]+1==len[q]){
                link[np]=q;
            }
            else{
                int nq=newnode(len[p]+1);
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                link[nq]=link[q],link[q]=link[np]=nq;
                for(;~p&&ch[p][c]==q;p=link[p])ch[p][c]=nq;
            }
        }
        last=np;
    }
}sam;

struct Palindromic_Tree{
    struct Node{
        int son[26];
        int ff,len;
    }t[maxn];
    int last,tot;
    void init(){
        t[++tot].len=-1;
        t[0].ff=t[1].ff=1;
    }
    void extend(int c,int n){
        int p=last;
        while(s[n-t[p].len-1]!=s[n])p=t[p].ff;
        if(!t[p].son[c]){
            int v=++tot,k=t[p].ff;
            t[v].len=t[p].len+2;
            while(s[n-t[k].len-1]!=s[n])k=t[k].ff;
            t[v].ff=t[k].son[c];
            t[p].son[c]=v;
        }
        last=t[p].son[c];
    }
}mm;

int main(){
    scanf("%s",s+1);
    int len=strlen(s+1);
    sam.init();
    for(int i=1;s[i];i++){
        sam.extend(s[i]-'a');
    }
    sam.last=0;
    for(int i=len;i;i--){
        sam.extend(s[i]-'a');
    }
    ll ans=0;
    for(int i=1;i<sam.sz;i++){
        ans+=sam.len[i]-sam.len[sam.link[i]];
    }
    mm.init();
    for(int i=1;i<=len;i++){
        mm.extend(s[i]-'a',i);
    }
    ll pp=mm.tot-1;
    cout<<(ans+pp)/2<<endl;
    return 0;
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章