zoukankan      html  css  js  c++  java
  • I Love Palindrome String

     I Love Palindrome String

    时间限制: 2 Sec  内存限制: 128 MB

    题目描述

    You are given a string S=s1s2..s|S| containing only lowercase English letters. For each integer i∈[1,|S|] , please output how many substrings slsl+1...srsatisfy the following conditions:
     ∙ r−l+1 equals to i.
     ∙ The substring slsl+1...sr is a palindrome string.
     ∙ slsl+1...s⌊(l+r)/2⌋ is a palindrome string too.
    |S| denotes the length of string S.
    A palindrome string is a sequence of characters which reads the same backward as forward, such as madam or racecar or abba. 

    输入

    There are multiple test cases.
    Each case starts with a line containing a string S(1≤|S|≤3×105) containing only lowercase English letters.
    It is guaranteed that the sum of |S| in all test cases is no larger than 4×106.

    输出

    For each test case, output one line containing |S| integers. Any two adjacent integers are separated by a space.

    样例输入

    abababa
    

    样例输出

    7 0 0 0 3 0 0

    题意:求有多少个字符串为回文串,且它的前一半也是回文串。
    回文树+马拉车。先用回文树求出全部的本质不一样(就是长度不一样,或者长度一样内容不一样)的字符串,然后用马拉车快速判断该串是不是符合题意。
    #include<bits/stdc++.h>
    using namespace std;
    //https://www.xuebuyuan.com/3184341.html
    const int MAXN = 300005 ;
    const int N = 26 ;
     
    int Palindromic_Length[MAXN*2];
    int ans[MAXN];
     
     
    struct Palindromic_Tree
    {
        int nxt[MAXN][26],f[MAXN],cnt[MAXN],num[MAXN],len[MAXN],c[MAXN],last,n,L;
     
        int l[MAXN],r[MAXN];
     
        inline int newnode(int x)
        {
            for(register int i=0; i<26; ++i)
                nxt[L][i]=0;
            cnt[L]=0;
            len[L]=x;
            return L++;
        }
        void init()
        {
            L=0;
            newnode(0);
            newnode(-1);
            last=0;
            n=0;
            c[n]=-1;
            f[0]=1;
        }
        inline int getf(int x)
        {
            while(c[n-len[x]-1]!=c[n])
                x=f[x];
            return x;
        }
        inline void add(int x)
        {
            x-='a';
            c[++n]=x;
            int cur=getf(last);
            if(!nxt[cur][x])
            {
                int now=newnode(len[cur]+2);
     
                 l[now]=n-len[cur]-1;
                r[now]=n;
     
                f[now]=nxt[getf(f[cur])][x];
                nxt[cur][x]=now;
            }
            ++cnt[last=nxt[cur][x]];
        }
        void count()
        {
            for(register int i=L-1; i>=2; --i)
                cnt[f[i]]+=cnt[i];
        }
     
        void getans()
        {
            count();
            for(int i=2;i<L;i++)
            {
                int l1=l[i],r1=r[i];
                r1=(l1+r1)/2;
     
                r1*=2;
                l1*=2;
     
                int mid=(r1+l1)/2;
     
                if(mid-Palindromic_Length[mid]+1<=(l1))
                {
                    ans[len[i]]+=cnt[i];
                }
            }
        }
     
     
    } PT;
     
    string Manacher(string s)
    {
        /*改造字符串*/
        string res="$#";
        for(int i=0; i<s.size(); ++i)
        {
            res+=s[i];
            res+="#";
        }
     
        /*数组*/
        vector<int> P(res.size(),0);
        int mi=0,right=0;   //mi为最大回文串对应的中心点,right为该回文串能达到的最右端的值
        int maxLen=0,maxPoint=0;    //maxLen为最大回文串的长度,maxPoint为记录中心点
     
        for(int i=1; i<res.size(); ++i)
        {
            P[i]=right>i ?min(P[2*mi-i],right-i):1;     //关键句,文中对这句以详细讲解
     
            while(res[i+P[i]]==res[i-P[i]])
                ++P[i];
     
            if(right<i+P[i])    //超过之前的最右端,则改变中心点和对应的最右端
            {
                right=i+P[i];
                mi=i;
            }
     
            if(maxLen<P[i])     //更新最大回文串的长度,并记下此时的点
            {
                maxLen=P[i];
                maxPoint=i;
            }
            Palindromic_Length[i]=P[i]-1;
     
           // printf("%d %d %c
    ",i,P[i]-1,res[i]);
     
        }
        return s.substr((maxPoint-maxLen)/2,maxLen-1);
    }
     
    Palindromic_Tree tree;
    int main()
    {
        char s[MAXN];
     
        while(scanf("%s",s)==1)
        {
            string a(s);
            tree.init();
     
            int len=strlen(s);
            for(int i=0;i<len;i++)tree.add(s[i]),ans[i+1]=0;
            Manacher(a);
            tree.getans();
            for(int i=1;i<=len;i++)printf("%d%c",ans[i],i==len ? '
    ' : ' ');
        }
        //for(int i=0;i<a.size();i++)tree.add(a[i]);
        return 0;
     
    }
    View Code
  • 相关阅读:
    【Python-Django模型迁移】用户数据库模型的迁移(对其他数据库迁移同样适用)!!!
    【Python-Django定义用户模型类】Python-Django定义用户模型类详解!!!
    【OpenCV-ANN神经网络自动驾驶】树莓派OpenCV神经网络自动驾驶小车【源码+实物】
    【Python-Django】Jinja2模板引擎配置教程详解!!!!
    js实现事件委托
    前端里面如何进行搜索引擎优化(SEO)
    ajax的优缺点
    css中px,em,rem,rpx的区别
    margin与padding的bug
    css3动画:transition和animation
  • 原文地址:https://www.cnblogs.com/tian-luo/p/11254151.html
Copyright © 2011-2022 走看看