• bzoj3790 神奇项链


    Description

    母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
    母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。 

    Input

    输入数据有多行,每行一个字符串,表示目标项链的样式。 

    Output

    多行,每行一个答案表示最少需要使用第二个机器的次数。 

    Sample Input

    abcdcba 
    abacada 
    abcdef

    Sample Output

    0
    2
    5

    Hint

    每个测试数据,输入不超过 5行 
    每行的字符串长度小于等于 50000 
     
     
    manacher+贪心
     
    manacher:一种线性时间求回文串长度的算法(右转Baidu)
     
    用manacher处理出以某个点开始的最长回文串长度,问题就转变成区间覆盖问题
    用贪心跑一遍即可。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    using namespace std;
    template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
    template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
    char a[1000005],b[1000005];
    int p[1000005],f[1000005];
    int main(){
        while(scanf("%s",a)!=EOF){
            memset(f,0,sizeof(f));
            int len=strlen(a),n=0,id=0,mx=-1,last,mxd,ans=0;
            for(int i=0;i<len;++i) b[n++]='#',b[n++]=a[i];
            b[n++]='#';
            for(int i=0;i<n;++i){
                if(i<mx) p[i]=min(p[id*2-i],mx-i+1);
                else p[i]=1;
                while(i-p[i]>=0&&i+p[i]<n&&b[i-p[i]]==b[i+p[i]]) ++p[i];
                if(i+p[i]-1>mx) mx=i+p[i]-1,id=i;
                f[i-p[i]+1]=i+p[i]-1; //处理出从点i-p[i]+1开始的最长回文串长度
            }last=mxd=f[0]+2;
            for(int i=0;i<n;i+=2){ //贪心
                if(i==last) last=mxd,++ans;
                mxd=max(mxd,f[i]+2);
            }printf("%d
    ",ans);
        }return 0;
    }
  • 相关阅读:
    informix 外部表 pipe
    关于XML的一些解析操作
    oracle 导出导入数据库
    判断请求访问的浏览器类型设备
    git与SVN的区别
    Java获取文件路径
    <DIV>内容显示隐藏功能实现
    文件下载
    文件上传
    记录启动Nginx启动失败
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9710442.html
Copyright © 2020-2023  润新知