zoukankan      html  css  js  c++  java
  • #1589 : 回文子串的数量(Manacher)

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    给定一个字符串S,请统计S的所有|S| * (|S| + 1) / 2个子串中(首尾位置不同就算作不同的子串),有多少个是回文字符串?

    输入

    一个只包含小写字母的字符串S。

    对于30%的数据,S长度不超过100。

    对于60%的数据,S长度不超过1000。

    对于100%的数据,S长度不超过800000。

    输出

    回文子串的数量

    样例输入
    abbab
    样例输出
              8

    manacher算法,可以直接求出
    i 枚举中心位置,p[i] 记录i下标为中心的最长回文串半径,
    id记录已匹配的回文串中点下标,mx记录已匹配的回文串的右边界下标+1

    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define MOD 1000000007
    #define MX 800050
    
    int len;
    char temp[MX];
    char str[MX*2];
    int p[MX*2];
    LL ans;
    
    void Init()
    {
        len = 0, ans = 0;
        str[len++]='!';
        str[len++]='#';
        int t = strlen(temp);
        for (int i=0;i<t;i++)
        {
            str[len++]=temp[i];
            str[len++]='#';
        }
        memset(p,0,sizeof(p));
    }
    
    void Manacher()
    {
        int mx = 0, id =0;
        for (int i=1;i<len;i++)
        {
            p[i] = mx>i ? min(p[2*id-i],mx-i):1;
            while (i-p[i]>=0 && str[i+p[i]]==str[i-p[i]]) p[i]++;
            ans+=p[i]/2;
            if (i+p[i]>mx)
            {
                mx = i+p[i];
                id = i;
            }
        }
    }
    
    int main()
    {
        while (scanf("%s",temp)!=EOF)
        {
            Init();
            Manacher();
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
    
    
    
     
  • 相关阅读:
    【进阶指南学习笔记】lowbit
    POJ2288 Islands and bridges 【状态压缩,计数】
    POJ1995 Raising Modulo Numbers 快速幂
    CH0103 最短Hamilton路径 状态压缩
    【转载】bitset的用法 by 自为风月马前卒
    pytorch | A 60 MINUTE BLITZ 代码+详细注释
    NOI2019 游记
    十二省联考2019 游记
    python 从其他文件中引用函数
    HDU 6231 K-th Number
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7597383.html
Copyright © 2011-2022 走看看