zoukankan      html  css  js  c++  java
  • 【BZOJ-3790】神奇项链 Manacher + 树状数组(奇葩) + DP

    3790: 神奇项链

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 304  Solved: 150
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    abcdcba
    abacada
    abcdef

    Sample Output

    0
    2
    5

    HINT

    每个测试数据,输入不超过 5行 
    每行的字符串长度小于等于 50000 

    Source

    Solution

    用来当Manacher模板题..

    Manacher算法,一种线性求解最长回文串的算法,简单好写,也好懂,详细见这里:  折越

    这道题就是说,转换为多个回文串结合成一个新串,那么对目标串Manacher,对得到的回文串当做一条线段

    那么这题转为"线段覆盖"CodeVS上某题,贪心或者DP搞搞就可以了,这里利用树状数组优化一下

    这里的树状数组非常神奇,以前只知道树状数组能维护和,没想到可以维护后缀,做法和平常的正好相反

    Code

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 50010<<1
    int n,len,mx,id,p[maxn],cnt;
    char S[maxn>>1],s[maxn];
    struct TreeNode
    {
        int a[maxn];
        void init() {memset(a,127,sizeof(a));}
        int lowbit(int x) {return x&(-x);}
        int Query(int loc)
            {
                if (!loc) return 0;
                int x=0x7fffffff;
                for (int i=loc; i<=n; i+=lowbit(i))
                    x=min(x,a[i]);
                return x;
            }
        void Change(int loc,int D)
            {
                for (int i=loc; i; i-=lowbit(i))
                    a[i]=min(a[i],D);
            }
    }Tree;
    void PreWork()
    {
        cnt=0; mx=0; id=0;
        Tree.init(); memset(p,0,sizeof(p));
        n=strlen(S+1); len=n<<1|1;
        s[0]='$'; s[1]='#'; s[len+1]='%';
        for (int i=1; i<=n; i++)
            s[i<<1]=S[i],s[i<<1|1]='#';
    }
    struct HWCNode
    {
        int l,r;
        bool operator < (const HWCNode & A) const 
            {return r<A.r;}
    }Line[maxn];
    void Manacher()
    {
        PreWork();
        for (int i=1; i<=len; i++)
            {
                if (mx>i) p[i]=min(p[id*2-i],mx-i);
                    else p[i]=1;
                while (s[i-p[i]]==s[p[i]+i]) p[i]++;
                int x=(i-p[i])/2+1,y=(i+p[i])/2-1;
                if (x<=y) Line[++cnt].l=x,Line[cnt].r=y;
                if (p[i]+i>mx) mx=p[i]+i,id=i;
            }
    }
    int DP()
    {
        int ans=0x7fffffff;
        sort(Line+1,Line+cnt+1);
        for (int i=1; i<=cnt; i++)
            {
                int D=Tree.Query(Line[i].l-1)+1;
                Tree.Change(Line[i].r,D);
                if (Line[i].r==n) ans=min(ans,D);
            }
        return ans-1;
    }
    int main()
    {
        while (scanf("%s",S+1)!=EOF)
            Manacher(),printf("%d
    ",DP());
        return 0;
    }
  • 相关阅读:
    ACE_TASK学习
    tomcat:8005端口启动失败的解决办法
    centos7下安装jdk8
    解决github下载慢的一种方法
    page
    数据库
    做jar
    mvc:annotation-driven
    web.xml
    jsp九大内置对象el11内置对象
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5528412.html
Copyright © 2011-2022 走看看