zoukankan      html  css  js  c++  java
  • 【哈希和哈希表】Antisymmetry

    问题 H: 【哈希和哈希表】Antisymmetry

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 36  解决: 12
    [提交] [状态] [讨论版] [命题人:admin]

    题目描述

    对于一个0/1字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作「反对称」字符串。比如00001111和010101就是反对称的,而1001就不是。
    现在给出一个长度为n的0/1字符串,求它有多少个子串是反对称的,注意这里相同的子串出现在不同的位置会被重复计算。

    输入

    第一行一个正整数n。
    第二行一个长度为n的0/1字符串。

    输出

    一行一个整数,表示原串的反对称子串个数。

    样例输入

    8
    11001011
    

    样例输出

    7
    

    提示

    对于100%的数据,1≤n≤500000。

    思路:显然符合条件的字串长度为偶数,否则中间那位取反后不可能与原串相同。

    枚举前半部分最后一个位置(1~n-1),二分长度hash即可。

    #include<bits/stdc++.h>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define ull unsigned long long;
    #define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
    #define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
    #define PER(i, a, b) for(int i = (a); i >= (b); -- i)
    const int maxn = 5e5 + 5;
    using namespace std;
    char str[maxn];
    int n, a[maxn], b[maxn], gt;
    long long tot;
    int ha[maxn], hb[maxn], base[maxn];
    int funa(int l, int r) {
        return ha[r] - ha[l - 1] * base[r - l + 1];
    }
    int funb(int l, int r) {
        return hb[l] - hb[r + 1] * base[r - l + 1];
    }
    int main(){
        cin >> n;
        base[0] = 1;
        scanf("%s", str+1);
        REP(i, 1, n)a[i] = str[i] - '0', b[i] = a[i] ^ 1;
        REP(i, 1, n)ha[i] = ha[i - 1] * 131 + a[i], base[i] = base[i - 1] * 131;
        PER(i,n,1)hb[i] = hb[i+1] * 131 + b[i];
        for (int i = 1; i < n; i++) {
            int l = 1, r= min(i, n - i), mid;
            gt = 0;
            while (l <= r) {
                int mid = (l + r) / 2;
                if(funa(i-mid+1,i+mid)==funb(i-mid+1,i+mid))gt=mid,l=mid+1;
                else r = mid - 1;
            }
            tot += gt;
        }
        cout<<tot<<endl;
    }
  • 相关阅读:
    两栏自适应布局
    说说bfc 和 HasLayout
    春联式弹动广告
    Centos7安装完毕后重启提示Initial setup of CentOS Linux 7 (core)的解决方法
    2016年新剧《欢乐颂》里面的经典台词
    硬盘怎么保养
    如何保养与维护笔记本硬盘
    仔细看完,你会成为微信高手
    电脑之间用网线直接连接起来快速传送大文件技巧
    阿里云9折优惠码 GQH4IT 使用方法如下:
  • 原文地址:https://www.cnblogs.com/czy-power/p/10357495.html
Copyright © 2011-2022 走看看