• POWEROJ 2610 判断回文串 【HASH】


    题目链接【https://www.oj.swust.edu.cn/problem/show/2610】

    题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e7,内存是4096KB。

    题解:首先这1e7个字符是存不下的,1e71024=9765KB>4096kB。那么怎么办?字符串哈希,先对字符串的前半部分进行哈希,然后在对字符串后半部分进行哈希,如果两部分的哈希值相同,那么这个字符串就是回文串。

    BKDRH哈希,哈希公式为has=has*seed+s[i],seed为31,131,1313,这里选择131。对于后半部分has+=pow(seed,i-1)*s[i]。但是这样哈希会有漏洞,需要更近一步的完善,我们用unsigned long long 存HAS值,所以他会自动取模(2^64-1),

    对于前半部分我们维护两个HAS值,分别对两个不同的素数取模,后半部分也一样。那么我们就维护这两对哈希值,只有当这两对哈希值都分别相等的时候,我们才认为这两段字符串是相等的,也就是回文串。具体看代码。

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ULL;
    const ULL modA = 1e9 + 7;
    const ULL modB = 1e9 + 9;
    ULL has[5], SEED = 131;
    int N;
    int main ()
    {
        while(~scanf("%d", &N))
        {
            has[0] = has[1] = 0;
            has[2] = has[3] = 0;
            char s;
            char S[5];
            gets(S);
            for(int i = 1; i <= N / 2; i++)
            {
                s = getchar();
                ULL t = (ULL)s;
                has[0] = (has[0] * SEED + t) % modA;
                has[1] = (has[1] * SEED + t) % modB;
            }
            if(N % 2) s = getchar();
            ULL seed[3];
            seed[0] = seed[1] = seed[2] = (ULL)1;
            for(int i = 1; i <= N / 2; i++)
            {
                s = getchar();
                ULL t = (ULL)s ;
                has[2] = (has[2] + t * seed[0]) % modA;
                has[3] = (has[3] + t * seed[1]) % modB;
                seed[0] = seed[0] * SEED % modA;
                seed[1] = seed[1] * SEED % modB;
            }
            if(has[0] == has[2] && has[1] == has[3] )
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    类的封装和隐藏
    函数的装饰器
    vue嗯嗯
  • 原文地址:https://www.cnblogs.com/pealicx/p/6591332.html
Copyright © 2020-2023  润新知