首页 > 代码库 > Power oj/2610[判断回文串]
Power oj/2610[判断回文串]
题目链接【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\n"); else printf("NO\n"); } return 0; }
Power oj/2610[判断回文串]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。