zoukankan      html  css  js  c++  java
  • 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第一题啊
    这是一个O(n)的找回文串的算法
    首先找出以每一位为中心的最长回文子串的区间,问题变成取最少的区间完全覆盖整个区间
    排个序贪心就好了。显然是相同个数的区间尽量凑出右边界尽可能大的更优
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<deque>
    #include<set>
    #include<map>
    #include<ctime>
    #define LL long long
    #define inf 0x7ffffff
    #define pa pair<int,int>
    #define pi 3.1415926535897932384626433832795028841971
    using namespace std;
    inline LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void write(LL a)
    {
    	if (a<0){printf("-");a=-a;}
    	if (a>=10)write(a/10);
    	putchar(a%10+'0');
    }
    inline void writeln(LL a){write(a);printf("
    ");}
    int len,cnt,tot,now,ans;
    char ch[100010],s[100010];
    int p[100010];
    struct srt{int l,r;}a[100010];
    bool operator <(srt a,srt b){return a.l<b.l||a.l==b.l&&a.r<b.r;}
    inline void manacher()
    {	
    	cnt=tot=0;int mx=0,id=0;
    	for (int i=1;i<=len;i++)
    	{
    		s[++cnt]='#';
    		s[++cnt]=ch[i];
    	}
    	s[++cnt]='#';
    	s[0]='$';
    	for (int i=2;i<cnt;i++)
    	{
    		if (p[id]+id>i)p[i]=min(p[2*id-i],p[id]-(i-id));
    		else p[i]=1;
    		while (s[i+p[i]]==s[i-p[i]])p[i]++;
    		if (p[i]+i>p[id]+id)id=i;
    	}
    	memset(a,0,sizeof(a));
    	for (int i=1;i<=cnt;i++)
    	{
    		int res=p[i]-1;
    		int l=i-res,r=i+res;
    		if (l%2)l++;if (r%2)r--;
    		l/=2;r/=2;
    		if (l>r)continue;
    		a[++tot].l=l;
    		a[tot].r=r;
    	}
    }
    inline void work()
    {
    	len=strlen(ch+1);
    	manacher();
    	sort(a+1,a+tot+1);
    	now=ans=0;int i=1;
    	while (now!=len)
    	{
    		int to=-1;
    		while (a[i].l<=now+1&&i<=tot)
    			to=max(to,a[i].r),i++;
    		now=to;ans++;
    	}
    	printf("%d
    ",ans-1);
    }
    int main()
    {
    	while (~scanf("%s",ch+1))work();
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    Java中的4种代码块
    Java enum(枚举)的用法详解(转)
    Java 可变参数列表
    SQL Server 查询处理中的各个阶段(SQL执行顺序)
    SQL Server 数据查询 整理
    MYSQL常用命令
    SQL的主键和外键约束(转)
    Servlet工作原理(转)
    servlet、genericservlet、httpservlet之间的区别(转)
    关于MyEcplise中常见的问题和解决方案
  • 原文地址:https://www.cnblogs.com/zhber/p/4181406.html
Copyright © 2011-2022 走看看