JSOI2016扭动的回文串

Posted shxnb666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSOI2016扭动的回文串相关的知识,希望对你有一定的参考价值。

题面

https://www.luogu.org/problem/P4324

题解

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100050
#define uLL unsigned long long
#define ri register int
using namespace std;

const uLL p=1233107;
int n;
char s[2][N];
uLL sump[2][N],sumq[2][N],pp[N];
int ji[2][N],ou[2][N];
int ansp;

inline uLL hashp(int o,int l,int r)if (l>r || r>n || l<1) return 0;return sump[o][r]-sump[o][l-1]*pp[r-l+1];
inline uLL hashq(int o,int l,int r)if (l>r || r>n || l<1) return 0;return sumq[o][l]-sumq[o][r+1]*pp[r-l+1];

int main()  
  pp[0]=1;
  for (ri i=1;i<N;i++) pp[i]=pp[i-1]*p;
  scanf("%d",&n);
  scanf("%s",s[0]+1);
  scanf("%s",s[1]+1);

  for (ri i=1;i<=n;i++) 
    for (ri j=0;j<=1;j++) sump[j][i]=sump[j][i-1]*p+s[j][i]-A;
  for (ri i=n;i>=1;i--) 
    for (ri j=0;j<=1;j++) sumq[j][i]=sumq[j][i+1]*p+s[j][i]-A;

  for (ri i=1;i<=n;i++)
    for (ri j=0;j<=1;j++) 
      int lb=0,rb=min(i-1,n-i);
      while (lb<=rb) 
        int mid=(lb+rb)/2;
        if (hashp(j,i-mid,i-1)==hashq(j,i+1,i+mid)) ji[j][i]=max(ji[j][i],mid),lb=mid+1; else rb=mid-1;
      
    
  for (ri i=1;i<=n-1;i++) 
    for (ri j=0;j<=1;j++) 
      int lb=0,rb=min(i,n-i);
      while (lb<=rb) 
        int mid=(lb+rb)/2;
        if (hashp(j,i-mid+1,i)==hashq(j,i+1,i+mid)) ou[j][i]=max(ou[j][i],mid),lb=mid+1; else rb=mid-1;
      
    
  int ans=0;
  for (ri i=1;i<=n;i++)
    for (ri j=0;j<=1;j++) 
      if (ou[j][i]*2>ans) ans=ou[j][i]*2,ansp=-1;
      if (ji[j][i]*2+1>ans) ans=ji[j][i]*2+1,ansp=-1;
    

  for (ri i=1;i<=n;i++) 
    for (ri j=0;j<=1;j++) 
      if (j==0) 
        int x=i+ji[j][i];
        int lb=ji[j][i]+1,rb=min(i-1,n-i+1);
        while (lb<=rb) 
          int mid=(lb+rb)/2;
          if (hashp(j,i-mid,i-1)==hashq(j,i+1,x)+hashq(j^1,x,i+mid-1)*pp[ji[j][i]]) 
            if (2*mid+1>ans) ans=2*mid+1,ansp=0;
            lb=mid+1; 
          
          else rb=mid-1;
        
      
      else 
        int y=i-ji[j][i];
        int lb=ji[j][i]+1,rb=min(i,n-i);
        while (lb<=rb) 
          int mid=(lb+rb)/2;
          if (hashq(j,i+1,i+mid)==hashp(j,y,i-1)+hashp(j^1,i-mid+1,y)*pp[ji[j][i]]) 
            if (2*mid+1>ans) ans=2*mid+1,ansp=1;
            lb=mid+1; 
          
          else rb=mid-1;
        
      
    

  for (ri i=1;i<=n-1;i++) 
    for (ri j=0;j<=1;j++) 
      if (j==0) 
        int x=i+ou[j][i];
        int lb=ou[j][i]+1,rb=min(i,n-i+1);
        while (lb<=rb) 
          int mid=(lb+rb)/2;
          if (hashp(j,i-mid+1,i)==hashq(j,i+1,x)+hashq(j^1,x,i+mid-1)*pp[ou[j][i]]) 
            if (2*mid>ans) ans=2*mid,ansp=2;
            lb=mid+1;
          
          else rb=mid-1;
        
      
      else 
        int y=i-ou[j][i]+1;
        int lb=ou[j][i]+1,rb=min(i+1,n-i);
        while (lb<=rb) 
          int mid=(lb+rb)/2;
          if (hashq(j,i+1,i+mid)==hashp(j,y,i)+hashp(j^1,i-mid+2,y)*pp[ou[j][i]]) 
            if (2*mid>ans) ans=2*mid,ansp=3;
            lb=mid+1;
          
          else rb=mid-1;
        
      
    
  cout<<ans<<endl;

 

以上是关于JSOI2016扭动的回文串的主要内容,如果未能解决你的问题,请参考以下文章

P4324 [JSOI2016]扭动的回文串

JSOI2016扭动的回文串

[BZOJ]4755: [Jsoi2016]扭动的回文串

loj2073 「JSOI2016」扭动的回文串

腾讯2016春招之算法编程解析

「APIO2014」回文串 (二分+hash)