zoukankan      html  css  js  c++  java
  • 回文串(bzoj 3676)

    Description

    考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 
    现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 
    大出现值。 

    Input

    输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。 

    Output


    输出一个整数,为逝查回文子串的最大出现值。 

    Sample Input

    【样例输入l】
    abacaba

    【样例输入2]
    www

    Sample Output

    【样例输出l】
    7

    【样例输出2]
    4

    HINT



    一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。 

    在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中: 

    ● a出现4次,其出现值为4:1:1=4 

    ● b出现2次,其出现值为2:1:1=2 

    ● c出现1次,其出现值为l:1:l=l 

    ● aba出现2次,其出现值为2:1:3=6 

    ● aca出现1次,其出现值为1=1:3=3 

    ●bacab出现1次,其出现值为1:1:5=5 

    ● abacaba出现1次,其出现值为1:1:7=7 

    故最大回文子串出现值为7。 

    【数据规模与评分】 

    数据满足1≤字符串长度≤300000。

    /*
        调了一个晚上,终于调出来了,二分的时候出了一些差错。
        因为一个长度为n的字符串,本质不同的回文串只有n个,所以这个题很明显需要处理出所有的回文串,然后再查询字符串中它出现的次数。
        提前处理出height数组,然后查询某个字串的时候,找到它的排名,向上向下二分查询次数。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 300100
    #define lon long long
    using namespace std;
    int s[N],t1[N],t2[N],c[N],sa[N],rank[N],height[N],n,m=26;
    int p[N*2],st[N][20],lg2[N];
    char ch[N],s1[N*2];lon ans;
    bool cmp(int *y,int a,int b,int k){
        int a1=y[a],b1=y[b];
        int a2=a+k<n?y[a+k]:-1;
        int b2=b+k<n?y[b+k]:-1;
        return a1==b1&&a2==b2;
    }
    void DA(){
        int *x=t1,*y=t2;
        for(int i=0;i<m;i++) c[i]=0;
        for(int i=0;i<n;i++) c[x[i]=s[i]]++;
        for(int i=1;i<m;i++) c[i]+=c[i-1];
        for(int i=n-1;~i;i--) sa[--c[x[i]]]=i;
        for(int k=1,p=0;k<=n;k*=2,m=p,p=0){
            for(int i=n-k;i<n;i++) y[p++]=i;
            for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
            for(int i=0;i<m;i++) c[i]=0;
            for(int i=0;i<n;i++) c[x[y[i]]]++;
            for(int i=1;i<m;i++) c[i]+=c[i-1];
            for(int i=n-1;~i;i--) sa[--c[x[y[i]]]]=y[i];
            swap(x,y);p=1;x[sa[0]]=0;
            for(int i=1;i<n;i++)
                if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
                else x[sa[i]]=p++;
            if(p>=n) break;
        }
    }
    void get_ht(){
         for(int i=0;i<n;i++) rank[sa[i]]=i;
        for(int i=0,j,k=0;i<n;height[rank[i++]]=k){
            if(!rank[i]) continue;
            j=sa[rank[i]-1];k=k?k-1:k;
            while(j+k<n&&i+k<n&&s[i+k]==s[j+k]) k++;
        }
        memset(st,127/3,sizeof(st));
        for(int i=0;i<n;i++) st[i][0]=height[i];
        for(int i=2;i<=n;i++) lg2[i]=lg2[i>>1]+1;
        for(int j=1;1<<j<=n;j++)
            for(int i=0;i+(1<<j)-1<n;i++)
                st[i][j]=min(st[i][j-1],st[i+(1<<j-1)][j-1]);
    }
    int query(int l,int r){
        if(l>r) return 0;
        int k=lg2[r-l+1];
        return min(st[l][k],st[r-(1<<k)+1][k]);
    }
    lon solve(int l,int r){
        l=(l&1)?l/2:l/2-1;
        r=(r&1)?r/2-1:r/2-1;
        if(l==0&&r==1){
            int aa=1;
        }
        int pos=rank[l],L=-1,R=pos,tmp1=pos,tmp2=pos;
        while(L<R-1){
            int mid=L+R>>1;
            if(query(mid+1,pos)>=r-l+1) R=mid,tmp1=mid;
            else L=mid;
        }
        L=pos;R=n;
        while(L<R-1){
            int mid=L+R>>1;
            if(query(pos+1,mid)>=r-l+1) L=mid,tmp2=mid;
            else R=mid;
        }
        return (lon)(tmp2-tmp1+1)*(r-l+1);
    }
    void manacher(){
        int len=n*2+1;
        s1[0]='$';s1[len]='#';
        for(int i=0;i<n;i++){
            s1[i*2+1]='#';
            s1[i*2+2]=ch[i];
        }
        p[1]=1;int pos=1,maxr=1;
         for(int i=2;i<=len;i++){
            if(i<maxr) p[i]=min(maxr-i,p[pos*2-i]);
            else p[i]=1;
            while(s1[i+p[i]]==s1[i-p[i]]){
                if(i+p[i]>maxr) ans=max(ans,solve(i-p[i],i+p[i]));
                p[i]++;
            }
            if(i+p[i]>maxr) pos=i,maxr=i+p[i];
        }
    }
    int main(){
        scanf("%s",ch);n=strlen(ch);
        for(int i=0;i<n;i++) s[i]=ch[i]-'a';
        DA();get_ht();
        manacher();
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    (总结)MySQL my.cnf参数配置优化详解
    CentOS下安装使用流量监控工具iftop
    ssh登录亚马逊aws
    linux nat squid ntop
    jquery动态添加Div
    为什么st2 chrome无法显示api中的例子
    使用jquery当页面打开时,将修改样式的点击事件绑定到Dom
    jquery动态添加Div
    使用jquery当页面打开时,将修改样式的点击事件绑定到Dom
    sencha touch 2 mvc调用文件顺序
  • 原文地址:https://www.cnblogs.com/harden/p/6591934.html
Copyright © 2011-2022 走看看