zoukankan      html  css  js  c++  java
  • [bzoj] 2565 最长双回文串

    原题

    双回文串的定义是“回文串回文串”,所以答案就是以i结尾的最长回文串长度加上以i+1为开头的最长回文串的长度

    然而怎么处理作为结尾时的长度和作为开头时的长度呢?n^2肯定是不行的啊!

    Eg:求结尾数组
    对于当前i结尾的ans,一定越早更新他的越长,所以像manacher一样,记录一个右端点,如果i>maxr那么暴力更新,否则不用更新。而且每个位置只用被更新一遍,也就是O(n)的了
    开头数组是同理的

    #include<cstdio>
    #include<algorithm>
    #define N 200010
    using namespace std;
    int l=1,now,ans,lft[N],rght[N],a[N],mxr,p;
    char s[N],c;
    
    int main()
    {
        s[0]='@';
        while (~scanf("%c",&c))
        {
    	if (c=='
    ') break;
    	s[l++]='#';
    	s[l++]=c;
        }
        s[l++]='#';
        s[l++]='?';
        for (int i=1,q;i<=l;i++)
        {
    	if (mxr>i) q=min(mxr-i,a[2*p-i]);
    	else q=1;
    	while (s[i-q]==s[i+q]) q++;
    	a[i]=q;
    	if (i+q>mxr) mxr=i+q,p=i;
        }
        for (int i=1;i<=l;i++)
        {
    	if (i+a[i]>now)
    	{
    	    for (int j=now+1;j<=i+a[i];j++)
    		if (s[j]!='#') lft[j]=j-i+1;
    	    now=i+a[i]-1;
    	}
        }
        now=l-1;
        for (int i=l-1;i>=1;i--)
        {
    	if (i-a[i]<now)
    	{
    	    for (int j=now-1;j>=i-a[i];j--)
    		if (s[j]!='#') rght[j]=i-j+1;
    	    now=i-a[i]+1;
    	}
        }
        for (int i=2;i<=l;i+=2)
    	if (s[i]!='#') ans=max(ans,lft[i]+rght[i+2]);
        printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    用php爬取网页
    无论我是一只菜鸟笨鸟
    有线网卡与无线网卡同时使用
    scapy 命令理解
    Wireshark Filter
    python OS/pdb 模块及数据类型基础
    scapy down and install
    python 字符操作函数
    python 类型集
    python 科学计算
  • 原文地址:https://www.cnblogs.com/mrha/p/7879698.html
Copyright © 2011-2022 走看看