• [BZOJ2565] 最长双回文串


    题目链接

    BZOJ.

    洛谷.

    Solution

    随便跳的题...

    先跑一边(manacher)

    很容易想到一个做法,处理出(l[i])表示以(i)结尾的回文串最大长度,(r[i])表示以(i)开头。

    那么如何处理出这个呢,可以发现,(l[i])其实就是回文中心离(i)最远的,且回文可以波及到(i)

    那么直接拿个指针指一下扫过去就好了。

    最后处理答案就是枚举断点,前面是(l[i])后面是(r[i])

    细节还是有一点的。

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    #define ll long long 
    
    const int maxn = 2e5+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    
    char c[maxn],s[maxn];
    int n,mid,mr,m,p[maxn],l[maxn],r[maxn];
    
    void solve(int *res) {
    	memset(p,0,sizeof p);n=0;
    	m=strlen(c+1);s[0]='$',s[++n]='#';
    	for(int i=1;i<=m;i++) s[++n]=c[i],s[++n]='#';mid=mr=1;
    	for(int i=1;i<=n;i++) {
    		p[i]=min(p[mid*2-i],mr-i);
    		while(s[i+p[i]]==s[i-p[i]]) p[i]++;
    		if(i+p[i]>mr) mr=i+p[i],mid=i;
    	}
    	
    	int t=1;
    	for(int i=1;i<=n;i++) {
    		while(t+p[t]-1<i) t++;
    		res[i]=(i-t)*2+1;
    	}
    }
    
    int main() {
    	scanf("%s",c+1);solve(l);
    	reverse(c+1,c+strlen(c+1)+1);
    	solve(r);int ans=0;reverse(r+1,r+n+1);
    	for(int i=2;i<n-1;i+=2) ans=max(ans,l[i]/2+1+r[i+2]/2+1);
    	for(int i=3;i<n;i+=2) ans=max(ans,max(l[i]/2+r[i+1]/2+1,l[i-1]/2+1+r[i]/2));
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    python操作MySQL数据库
    用python监控您的window服务
    关于position定位中的几个注意点
    filter 滤镜
    git使用心得
    :after,:before,content
    outline和border
    《css揭秘》之背景与边框
    css权威指南学习笔记--第6章
    浅谈setTimeout和setInterval
  • 原文地址:https://www.cnblogs.com/hbyer/p/10630421.html
Copyright © 2020-2023  润新知