zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp

    题目链接:

    http://codeforces.com/problemset/problem/7/D

    D. Palindrome Degree

    time limit per test1 second
    memory limit per test256 megabytes
    #### 问题描述 > String s of length n is called k-palindrome, if it is a palindrome itself, and its prefix and suffix of length are (k - 1)-palindromes. By definition, any string (even empty) is 0-palindrome. > > Let's call the palindrome degree of string s such a maximum number k, for which s is k-palindrome. For example, "abaaba" has degree equals to 3. > > You are given a string. Your task is to find the sum of the palindrome degrees of all its prefixes. #### 输入 > The first line of the input data contains a non-empty string, consisting of Latin letters and digits. The length of the string does not exceed 5·106. The string is case-sensitive. #### 输出 > Output the only number — the sum of the polindrome degrees of all the string's prefixes.

    样例输入

    a2A

    样例输出

    1

    样例输入

    abacaba

    样例输出

    6

    题意

    假设前缀prei是k-回文串(k=a[i])。则求ans=sigma(a[i])。

    题解

    用manacher算法处理出最左端为第一个字母的所有回文串,然后dp一下。
    dp[i]表示长度为i的前缀是k-回文串(k=dp[i])。 则dp[i]=dp[i/2]+1;
    ans=sigma(dp[i]);

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long  LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=1e7+10;
    
    char s[maxn];
    //P[i]表示把回文串折叠起来的长度
    //mx表示当前计算出来的回文串往右延伸的最远端
    //d表示贡献出mx的串的回文中心
    int P[maxn],mx,id,n;
    LL dp[maxn];
    
    LL solve(){
        LL ret=0;
        int len=strlen(s+1);
        n=len*2+1;
        s[0]='$',s[n]='#',s[n+1]='';
        for(int i=len*2;i>=1;i--){
            if(i&1) s[i]='#';
            else s[i]=s[i/2];
        }
    //    puts(s);
        clr(dp,0);
        mx=1,id=0;
        for(int i=1;i<=n;i++){
            //优化的核心,画画图比较好理解,j=2*id-i表示i关于id对称的点
            P[i]=mx>i?min(mx-i,P[2*id-i]):1;
            int k=i+P[i];
            while(s[k]==s[2*i-k]) k++,P[i]++;
            if(2*i-k==0&&i>1){
    //            bug(i);
                int l=P[i]-1;
                dp[l]=dp[l/2]+1;
                ret+=dp[l];
            }
            if(k>mx){
                mx=k;
                id=i;
            }
        }
        return ret;
    }
    
    int main() {
        scf("%s",s+1);
        LL ans=solve();
        prf("%I64d
    ",ans);
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    为linux系统添加虚拟内存swap分区
    使用exec命令删除前几天产生的日志
    编写脚本:访问一网站,每5分钟访问一次,如果访问成功,将访问记录保存到日志,如果访问失败,则发送邮件至指定邮箱
    html,css学习实践总结
    css清除浮动
    bootstrap简单使用
    jquery笔记
    HTML,CSS笔记
    node学习: package.json
    node笔记
  • 原文地址:https://www.cnblogs.com/fenice/p/5844257.html
Copyright © 2011-2022 走看看