CodeForces --- 961F: k-substrings [half] + Hash

Questions surface:

In the face of questions here ~~~

Meaning of the questions:

Given a string, and the same request a longest prefix and suffix for each k-substrings

analysis:

Since a lot of inquiries, do not run the kmp; readily occur before attempting the same binary hash length + suffix, but it does not have monotonic; length of the prefix and suffix to subject to an odd number, considering the midpoint of the front fixing suffix to spread to both sides , so that again two points on the radius of the diffusion of the monotone, the midpoint of such fixed prefix: X, then the midpoint of the suffix is: N-X + 1, which is obtained while the half spread to both sides of the maximum radius: R, then can be obtained before the two identical positions suffix contributions: X-R + 1, but it can also have the same prefix and suffix R-2, and so on for the X-R + 1 + 1 the contribution radius position, it is: dp [i] = max (dp [i], dp [i-1] -2), Note: If the length of the original string is odd, the point is not intermediate as a fixed half to a midpoint, this will lead to a length equal to the answer original string is not intended to meet the problem, in other cases, two midpoint fixing always symmetrical, its contribution to the natural length is less than the original string

This question card out of the natural overflow hash ~~~

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ull;
const int base = 233;
const int mod = 1e9+7;
const int maxn = 2e6+16;
int n,dp[maxn];
char s[maxn];
ull Hash[maxn],Pow[maxn];
void getfail(){
     Pow[0] = 1;
     for(int i=1;i <= n; ++i){
        Pow[i] = Pow[i-1]*base%mod;
        Hash[i] = (Hash[i-1]*base + (ull)s[i])%mod;
     }
}
ull getval(int l,int r){
    return (Hash[r]-Hash[l-1]*Pow[r-l+1]%mod+mod)%mod;
}
void solve(int len){
    getfail();
    for(int i = 1;i <= len; ++i){
        int l = 1,r = i,x = n-i+1;
        while(l <= r){
            int mid = (l+r)>>1;
            if(getval(i-mid+1,i+mid-1)==getval(x-mid+1,x+mid-1)) l=mid+1;
            else r = mid-1;
        }
        dp[i-r+1] = max(dp[i-r+1],2*r-1);
    }
}
int main(){
    scanf("%d %s",&n,s+1);
    solve(n/2);
    for(int i = 1;i <= n/2; ++i){
        dp[i] = max(dp[i],dp[i-1]-2);
        if(dp[i]) printf("%d ",dp[i]);
        else printf("-1 ");
    }
    if(n&1) printf("-1\n");
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_41157137/article/details/93139230