题很水,但是我第一发前缀和没有处理到n+1,第二发哈希底数137 mod 1e9+7被卡,第三发双哈希一个取模一个自然溢出都用ULL,取模的那个中间过程出现负数自动模了264。。。时运不齐,命途多舛。
双哈希先用自然溢出的判断会快很多,减少取模。
Code:
#include<bits/stdc++.h>
#define maxn 800005
using namespace std;
const int Seed = 137, mod = 1e9+7;
typedef unsigned long long ULL;
typedef long long LL;
struct str{
char s[maxn];
int n;
ULL F[maxn][2],p[maxn][2],G[maxn][2],f[maxn]; LL sum[maxn];
inline int V(int l,int r,bool t){
if(t) return F[r][1]-F[l-1][1]*p[r-l+1][1];
return (F[r][0]+mod-F[l-1][0]*p[r-l+1][0]%mod)%mod;
}
inline bool check(int l,int r){
if(F[r][1]-G[l][1]!=(F[l-1][1]-G[r+1][1])*p[r-l+1][1]) return 0;
return (F[r][0]+mod-G[l][0]+(G[r+1][0]+mod-F[l-1][0])*p[r-l+1][0])%mod==0;
}
void build(bool flg){
n=strlen(s+1),p[0][0]=p[0][1]=1;
if(flg) reverse(s+1,s+1+n);
for(int i=1;i<=n;i++){
F[i][0]=(F[i-1][0]*Seed+s[i])%mod,p[i][0]=p[i-1][0]*Seed%mod;
F[i][1]=(F[i-1][1]*Seed+s[i]),p[i][1]=p[i-1][1]*Seed;
}
for(int i=n;i>=1;i--)
G[i][0]=(G[i+1][0]*Seed+s[i])%mod,G[i][1]=G[i+1][1]*Seed+s[i];
for(int i=1;i<=n;i++){
int l=0,r=min(i-1,n-i),mid;
while(l<r) mid=(l+r+1)>>1,check(i-mid,i+mid)?(l=mid):(r=mid-1);
f[i-l]++,f[i+1]--;
if(i<n){
l=0,r=min(i,n-i);
while(l<r) mid=(l+r+1)>>1,check(i-mid+1,i+mid)?(l=mid):(r=mid-1);
f[i-l+1]++,f[i+1]--;
}
}
for(int i=1;i<=n+1;i++) f[i]+=f[i-1],sum[i]=sum[i-1]+f[i];
}
}A,B;
int Q,x,y;
int main()
{
freopen("palindrome.in","r",stdin);
freopen("palindrome.out","w",stdout);
scanf("%*s%s%s%d",A.s+1,B.s+1,&Q);
A.build(0),B.build(1);
while(Q--){
scanf("%d%d",&x,&y);
int l=0,r=min(A.n-x,B.n-y)+1,mid;
while(l<r) mid=(l+r+1)>>1,
A.V(x,x+mid-1,1)==B.V(y,y+mid-1,1)&&A.V(x,x+mid-1,0)==B.V(y,y+mid-1,0)?(l=mid):(r=mid-1);
printf("%lld\n",A.sum[x+l]-A.sum[x]+B.sum[y+l]-B.sum[y]+l);
}
}