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;
    }
  • 相关阅读:
    JavaScript操作符instanceof揭秘
    Linux打开txt文件乱码的解决方法
    Working copy locked run svn cleanup not work
    poj 2299 UltraQuickSort 归并排序求解逆序对
    poj 2312 Battle City 优先队列+bfs 或 记忆化广搜
    poj2352 stars 树状数组
    poj 2286 The Rotation Game 迭代加深
    hdu 1800 Flying to the Mars
    poj 3038 Children of the Candy Corn bfs dfs
    hdu 1983 Kaitou Kid The Phantom Thief (2) DFS + BFS
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5528412.html
Copyright © 2011-2022 走看看