ICPC Central Europe Regional Contest 2019 A. ABB(哈希/马拉车)

https://ac.nowcoder.com/acm/contest/7817/A


通过分析题意发现要求求一个最长的回文子串,要求一段是结尾。

首先旺哥上来就reverse然后对应匹配,然后wa了将近十多发,同时在计蒜客oj交了这道题代码是能过的,赛后发现正确率98%,也就是卡了一组数据,具体哪组不得而知。

既然求最长回文子串,那么考虑算法的可以马拉车。但是我菜我不会。用字符串哈希来过。

注意哈希的时候最好双模数,虽然这题单模数也可以过。另外,哈希匹配的时候如果是减法,那么一定一定要+mod后再取mod。找了一晚上bug。

“所有的hash值都是取过模的,但是这个hash值乘以jie[]以后不一定会超过mod,如果接近mod的话就出现了负数,这些都是没法确定的啊”--旺哥

当然如果单模数的话用ull自然溢出取模不会有这个问题。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=4e5+100;
typedef long long LL;
const int P=131;
const int mod1=19260817;
const int mod2=19660813;
pair<LL,LL>jie[maxn];
pair<LL,LL> h1[maxn],h2[maxn];
char s[maxn];
bool check1(LL x,LL y)//x表示中心位置,y表示一半的长度 
{
	pair<LL,LL>H1,H2;
	H1.first=(h1[x-1].first%mod1-h1[x-1-y].first%mod1*jie[y].first%mod1+mod1)%mod1;
	H2.first=(h2[x+1].first%mod1-h2[x+y+1].first%mod1*jie[y].first%mod1+mod1)%mod1;
	
	H1.second=(h1[x-1].second%mod2-h1[x-1-y].second%mod2*jie[y].second%mod2+mod2)%mod2;
	H2.second=(h2[x+1].second%mod2-h2[x+y+1].second%mod2*jie[y].second%mod2+mod2)%mod2; 
	
	if(H1.first==H2.first&&H1.second==H2.second) return true;
	else return false;
}
bool check2(LL x,LL y)//x表示右半段的左端点,y表示一半的长度 
{
	pair<LL,LL>H1,H2;
	H1.first=(h1[x-1].first%mod1-h1[x-1-y].first%mod1*jie[y].first%mod1+mod1)%mod1;
	H2.first=(h2[x].first%mod1-h2[x+y].first%mod2*jie[y].first%mod1+mod1)%mod1;
	
	H1.second=(h1[x-1].second%mod2-h1[x-1-y].second%mod2*jie[y].second%mod2+mod2)%mod2;
	H2.second=(h2[x].second%mod2-h2[x+y].second%mod2*jie[y].second%mod2+mod2)%mod2;
	
	if(H1.first==H2.first&&H1.second==H2.second) return true; 
	else return false;
}
int main(void)
{
  //cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;scanf("%lld",&n);
  scanf("%s",(s+1));
  jie[0].first=1;jie[0].second=1;
  for(LL i=1;i<=n;i++) {
  	jie[i].first=jie[i-1].first*P%mod1;
  	
  	jie[i].second=jie[i-1].second*P%mod2;
  	
	h1[i].first=(h1[i-1].first*P+s[i])%mod1;
	
	h1[i].second=(h1[i-1].second*P+s[i])%mod2;
  }
  for(LL i=n;i>=1;i--){
  	
  	h2[i].first=(h2[i+1].first*P+s[i])%mod1;
  	
	h2[i].second=(h2[i+1].second*P+s[i])%mod2;
  }
  LL ans=0;
  for(LL i=n;i>=n/2;i--)
  {
  	if(i-1>=n-i&&check1(i,n-i))
  	{
  		ans=max(ans,2*(n-i)+1);	
	}
	if(i-1>=n-i+1&&check2(i,n-i+1))
	{
		ans=max(ans,2*(n-i+1));
	}
  }
  printf("%lld\n",n-ans);
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108899687
今日推荐