• LOJ 2452 对称 Antisymmetry——用hash求回文串数


    概念

    用hash求最长回文串/回文串数

    首先,易知,回文串具有单调性。

    如果字符串 $s[l...r]$ 为回文串串,那么 $s[x...y]$($l < x, y < r$ 且 $|l-x| = |r-y|$)也一定是回文串。

    因此,可以二分。

    通常,枚举一下起点或者中点,然后二分长度。

    这样复杂度为 $O(nlogn)$,逊色于马拉车 $O(n)$,但在时限不那么紧的情况下,hash也是不错的选择。

    例题

    题意:对于一个 0/1 串,如果将这个字符串 0 和 1 取反后,再将整个串反过来和原串一样,就称作「反对称」字符串。先给出一个长为 $n$ 的 0/1 串,求它有多少反对称字串。($1 leq nleq 500000$)

    分析:

    先正向求一遍hash,再反向求一遍hash(0,1互换)。

    枚举中点,判断左右两半的hash值是否相同。

    显然,不存在长度为奇数的反对称串。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef unsigned long long ull;
    typedef long long ll;
    const ull base = 233;
    const int maxn = 5e5 + 10;
    
    ull h1[maxn], h2[maxn], p[maxn];
    int n;
    ll ans;
    char s[maxn];
    
    ull get_h1(int l, int r)
    {
        return h1[r] - h1[l-1]*p[r-l+1];
    }
    ull get_h2(int l, int r)
    {
        return h2[l] - h2[r+1]*p[r-l+1];
    }
    
    int check(int x)
    {
        int l=1, r = min(x, n-x);
        int ans=0;
        while(l <= r)
        {
            int mid = (l+r) >> 1;
            if(get_h1(x-mid+1,x) == get_h2(x+1, x+mid))
            {
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        return ans;
    }
    
    int main()
    {
        scanf("%d%s", &n, s+1);
        p[0] = 1;
        for(int i = 1;i <= n;i++)
        {
            p[i] = p[i-1]*base;
            h1[i] = h1[i-1]*base + (ull)s[i];
        }
        for(int i = n;i >= 1;i--)  h2[i] = h2[i+1]*base + (ull)(s[i] == '0' ? s[i]+1 : s[i]-1);
    
        for(int i = 1;i < n;i++)  ans += check(i);
        printf("%lld
    ", ans);
        return 0;
    }

    参考链接:https://www.cnblogs.com/henry-1202/p/10321013.html

  • 相关阅读:
    git如何忽略特殊文件
    一文了解H5照片上传过程
    Vue组件通信方式(8种)
    H5 拍照图片旋转、压缩和上传
    Chrome插件推荐
    高效开发之使用Cmder替换cmd
    使用git配置ssh的文章推荐
    360极速浏览器如何默认设置必应搜索引擎
    notepad 多文档切换
    centos下kill、killall、pkill命令区别
  • 原文地址:https://www.cnblogs.com/lfri/p/11375498.html
Copyright © 2020-2023  润新知