P3501 [POI2010] Two points + Hash

Title

Portal P3501 [POI2010] ANT-Antisymmetry

answer

The string SSS is inverted to getr S rSr S , it can be observed that the substrings satisfying the conditions satisfy the properties similar to palindrome strings. Suppose the length isxxThe first character from the left of the symmetry center of the substring of x isiii,则有 S [ i − x + 1 , i ] = r S [ i + 1 , i + x ] S[i-x+1,i]=rS[i+1,i+x] S[ix+1,i]=rS[i+1,i+x] H a s h Hash H a s h pretreatmentS, r SS, rSS,r S , enumerate the center of symmetry, dichotomize the longest length of the substring that satisfies the condition, and update the answer at the same time.

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 500005, bs = 131;
char S[maxn], rS[maxn];
int N;
ull B[maxn], F[maxn], rF[maxn];

inline bool judge(int i, int x) {
    
     return F[i] - F[i - x] * B[x] == rF[i + 1] - rF[i + x + 1] * B[x]; }

int main()
{
    
    
    scanf("%d", &N);
    scanf("%s", S + 1);
    for (int i = 1; i <= N; ++i)
        rS[i] = S[i] == '0' ? '1' : '0';
    B[0] = 1;
    for (int i = 1; i <= N; ++i)
        B[i] = B[i - 1] * bs, F[i] = F[i - 1] * bs + S[i] - '0' + 1;
    for (int i = N; i; --i)
        rF[i] = rF[i + 1] * bs + rS[i] - '0' + 1;
    ll res = 0;
    for (int i = 1; i <= N; ++i)
    {
    
    
        int lb = 0, ub = min(i, N - i) + 1;
        while (ub - lb > 1)
        {
    
    
            int mid = (lb + ub) >> 1;
            if (judge(i, mid))
                lb = mid;
            else
                ub = mid;
        }
        res += lb;
    }
    printf("%lld\n", res);
    return 0;
}

Guess you like

Origin blog.csdn.net/neweryyy/article/details/114338147