• HYSBZ 2342-双倍回文(Manacher算法应用)


    在这里插入图片描述

    Input

    输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

    Output

    输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。
    Sample Input
    16

    ggabaabaabaaball
    Sample Output
    12
    HINT

    N<=500000
    (详情看注释,因为没有理解Manacher算法数组的含义,这道题没做出来,太菜了。)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=2e6+10;
    int n,m,f[maxn],g[maxn];
    char a[maxn],s[maxn];
    int main(void)
    {
    	while(cin>>n)
    	{
    		int i,r,p;
    		scanf("%s",a+1);
    		for(int i=1;i<=n;i++) 
    		 s[i<<1]=a[i],s[i<<1|1]='#';
    		s[0]='$',s[1]='#',s[m=(n+1)<<1]='@';
    		
    		for(r=p=0,f[1]=1,i=2;i<m;i++)
    		{
    			for(f[i]=r>i?min(r-i,f[p*2-i]):1;s[i-f[i]]==s[i+f[i]];f[i]++);
    			if(i+f[i]>r) r=i+f[i],p=i;
    		}
    		int ans=0;
    		//串的中心显然是填充字符,所以i初始值为3,并且i+=2。 
            for(int i=3;i<m;i+=2)
    		{
    		   int len=f[i]-1;
               while(len>3)
               { 
               	 if(len%4==0)
               	 {
               	 	//如果比当前答案小直接跳出循环,节省时间 
               	     if(len<ans) break;
               	     //找到串的左端 
    	           	 int l=i-len;
    	           	 
    				 int r=i;
    				 //找到左边串的中心 
    	           	 int m=(l+r)/2;
    	           	 //如果左边的串能覆盖到i,保证左边的串也为回文串。 
    	           	 if(m+f[m]-1>=i)
    	           	  ans=max(ans,len);            	 	
    			 }
    	         len-=2;
    		   }
    			
    		}  
    		printf("%d
    ",ans);
    	
    	
    	
    	}
    	
    	
    	return 0;
     } 
     /*
    8
    aaaaaaaa
    12
    abbaabbaabba
    12
    abaabaabaaba 
    */
    
  • 相关阅读:
    数字图像-概述
    Python-python打包编译成pyd或者.so,保护代码。
    计算机组成原理-概述
    9大开源云管理平台(CMP)
    计算机组成原理-CPU-CPU知识科普:秒懂主频、核心、线程、缓存、架构详解
    svn git协同管理
    DEVTMPFS
    关于flash擦除的方法
    SQLServer强制保存
    360极速浏览器无法正确getHours
  • 原文地址:https://www.cnblogs.com/qinjames/p/10554682.html
Copyright © 2020-2023  润新知