• 【字符串哈希】回文子串的最大长度


    传送门

    题意

    给定一个串,求最长的回文子串

    数据范围

    题解

    一个判定是不是回文串可以用一个长度表示回文半径
    枚举每一个点,假设当前点是 i
    每次都检查奇数长度和偶数长度
    奇数情况下分为 ({ i-len , i-1 })({ i +1 , i+len})
    子回文串长度就是(2 imes len + 1)
    偶数情况下分为({ i-len , i-1 })({ i , i+len-1 })

    遍历每一个点,然后二分回文半径的长度
    二分的时候
    最小长度应该是0
    奇数长度的时候,最大长度应该是开始到当前点前一个点,和当前点后一个点到结尾这两个长度的最小值
    偶数长度是当前点前一个点,和当前到最后的最小值

    Code

    #include <bits/stdc++.h>
    #define ull unsigned long long
    using namespace std;
    const int N=1e6+10,P=131;
    char s[N];
    int m;
    int t;
    ull h1[N],h2[N],p[N];
    ull geth1(int l,int r){
    	return h1[r]-(h1[l-1]*p[r-l+1]);
    }
    ull geth2(int l,int r){
    	return h2[l]-h2[r+1]*p[r-l+1];
    }
    int main(){
    	p[0]=1;
    	for(int i=1;i<=N;i++) p[i]=p[i-1]*P;
    
    	while(scanf("%s",s+1) && strcmp(s+1,"END")){
    		cout<<"Case "<<++t<<": ";
    		 int ans=0,len=strlen(s+1);
    		 h2[len+1]=0;
    		 for(int i=1;i<=len;i++) h1[i]=h1[i-1]*P+(s[i]-'a'+1);
    		 for(int i=len;i;i--) h2[i]=h2[i+1]*P+(s[i]-'a'+1);
    
    		 for(int i=1;i<=len;i++){
    		 	int l=0,r=min(i-1,len-i);//二分的是长度,即到左边和到右边长度的最大值
    		 	while(l < r){
    		 		int mid=l+r+1>>1;
    		 		if(geth1(i-mid,i-1) == geth2(i+1,i+mid))
    		 			l=mid;
    		 		else
    		 			r=mid-1;
    		 	}
    		 	ans=max(ans,l*2+1);
    
    		 	l=0,r=min(i-1,len-i+1); //当前点算右半边所以要+1
    
    		 	while(l<r){
    		 		int mid=l+r+1>>1;
    		 		if(geth1(i-mid,i-1) == geth2(i,i+mid-1))
    		 			l=mid;
    		 		else
    		 			r=mid-1;
    		 	}
    		 	ans=max(ans,l*2);
    		 }
    		 cout<<ans<<endl;
    	}
    
    }
    
  • 相关阅读:
    解决word启动时报找不到mathpage.wll错误
    单应性(homography)变换的推导
    深度残差网(deep residual networks)的训练过程
    《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
    jquery版结婚电子请帖
    jquery版小型婚礼(可动态添加祝福语)
    OOP感想
    前端笔试题解答
    jquery版瀑布流
    jquery版时钟(css3实现)
  • 原文地址:https://www.cnblogs.com/hhyx/p/15323919.html
Copyright © 2020-2023  润新知