• BZOJ3790:神奇项链(Manacher)


    Description

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

    Input

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

    Output

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

    Sample Input

    abcdcba
    abacada
    abcdef

    Sample Output

    0
    2
    5

    HINT

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

    Solution

    先manacher求出len数组
    然后问题就可以转化成线段区间完全覆盖问题
    贪心就可以了

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define N (100000+1000)
     6 using namespace std;
     7 
     8 struct Node{int x,y;}L[N];
     9 bool cmp(Node a,Node b){return a.x<b.x;}
    10 int n,tot,len[N];
    11 char a[N],s[N];
    12 
    13 void Manacher()
    14 {
    15     int x,mid=0,maxn=0;
    16     for (int i=1; i<=tot; ++i)
    17     {
    18         if (i>maxn) x=1;
    19         else x=min(maxn-i+1,len[mid*2-i]);
    20         while (s[i+x]==s[i-x]) ++x;
    21         len[i]=x;
    22         if (i+x-1>maxn) maxn=i+x-1,mid=i;
    23     }
    24 }
    25 
    26 int main()
    27 {
    28     while (scanf("%s",a)!=EOF)
    29     {
    30         n=strlen(a);
    31         tot=0;
    32         s[++tot]='@'; s[++tot]='#';
    33         for (int i=0; i<n; ++i)
    34             s[++tot]=a[i], s[++tot]='#';
    35         s[++tot]='$';
    36         Manacher();
    37         
    38         int cnt=0;
    39         for (int i=2; i<tot; ++i)
    40             L[++cnt].x=i-len[i]+1, L[cnt].y=i+len[i]-1;
    41         
    42         sort(L+1,L+cnt+1,cmp);
    43         int p=1,now=1,ans=0;
    44         while (now<tot-1)
    45         {
    46             int maxn=-1;
    47             while (p<=tot && L[p].x<=now+1) maxn=max(maxn,L[p].y),p++;
    48             now=maxn; ans++;
    49         }
    50         printf("%d
    ",ans-1);
    51     }
    52 }
  • 相关阅读:
    Leetcode No.121
    Leetcode No.97 ***
    (描述需要改进) Leetcode No.71 **
    (描述需要改进)Leetcode No.68 **
    Leetcode No.72 ***
    【笔记】存储位置/修改表/字符集.【3(完结创建表)】
    redis 事件驱动模型解析
    redis 官网文档学习笔记 简单翻译
    redis 官网文档 sentinel 简单翻译 && 简单总结QA
    redis 学习笔记 总
  • 原文地址:https://www.cnblogs.com/refun/p/9445745.html
Copyright © 2020-2023  润新知