2018 ICPC Nanjing M-Title Mediocre String Problem - Gym - 101981M

https://blog.csdn.net/KXL5180/article/details/90142634

http://fastvj.rainng.com/problem/Gym-101981M

http://codeforces.com/gym/101981/attachments

Following the practice of the previous article on M-question in Nanjing, I learned the practice of writing a string hash this time.

The first step is to preprocess the palindrome string with the same horse-drawn algorithm as the last one to get the number of strings starting at the left endpoint of s.

Then hash the s-string, then reverse the hash on the pair, and finally enumerate the positions of the same characters in the s-string as at the end of the t-string, then split the LCP length, and

ans+=length*sum[i]; that's it

The idea is similar to the last one, the only difference is that the LCP solution has changed

The time complexity is O(nlogn), but the excessive constant is much smaller than the suffix array, and hash will not time out if he is handsome enough.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+10;
const ll p=13131;
const ll mod=1e9+7;
char s[N],t[N],s_new[N];
int d[N],pos[N];
int init()
{
    int len=strlen(s);
    s_new[0]='$';
    s_new[1]='#';
    int j=2;
    for(int i=0;i<len;i++)
    {
        s_new[j++]=s[i];
        s_new[j++]='#';
    }
    s_new[j]='\0';
    return j;
}
void Manacher()
{
    int len=init();
    int id,mx=0;
    for(int i=1;i<len;i++)
    {
        if(i<mx) pos[i]=min(pos[2*id-i],mx-i);
        else pos[i]=1;
        while(s_new[i-pos[i]]==s_new[i+pos[i]])
            pos[i]++;
        if(mx<i+pos[i]){
            id=i;mx=i+pos[i];
        }
    }
    for(int i=2;i<len;i++)
    {
        if(s_new[i]=='#'&&pos[i]==1) continue;
        int x=i/2-pos[i]/2+1;
        int y=x+i/2+pos[i]/2-!(i&1);
        d[x]++;
        d[y/2+1]--;
    }
}
ll hs1[N],hs2[N],pw[N];

ll geths(ll *hs,int l,int r)
{
    return (hs[r]-hs[l-1]*pw[r-l+1]%mod+mod)%mod;
}

int ok(int len,int p,int t_len)
{
    ll t1=geths(hs1,p-len+1,p);
    ll t2=geths(hs2,t_len-len+1,t_len);
    if(t1==t2) return 1;
    return 0;
}

int main()
{
    pw[0]=1;
    for(int i=1;i<1000003;i++){
        pw[i]=pw[i-1]*p%mod;
    }
    scanf("%s%s",s,t);
    Manacher();
    int len=strlen(s);
    for(int i=1;i<=len;i++) {
        d[i]+=d[i-1];
    }
    hs1[0]=hs2[0]=1;
    for(int i=0;i<len;i++){
        hs1[i+1]=(hs1[i]*p+s[i])%mod;
    }
    int t_len=strlen(t);
    reverse(t,t+t_len);
    for(int i=0;i<t_len;i++){
        hs2[i+1]=(hs2[i]*p+t[i])%mod;
    }
    ll ans=0;
    for(int i=0;i<len-1;i++){
        if(s[i]!=t[t_len-1]) continue;
        int l=1,r=min(i+1,t_len),mid,cnt=0;
        while(l<=r){
            mid=(l+r)>>1;
            if(ok(mid,i+1,t_len))
                cnt=mid,l=mid+1;
            else
                r=mid-1;
        }
        ans+=1LL*cnt*d[i+2];
    }
    printf("%lld\n",ans);
    return 0;
}

 

Posted by alfieshooter on Thu, 07 Nov 2019 11:28:15 -0800