HDU-5340 Three Palindromes(字符串哈希)

http://acm.hdu.edu.cn/showproblem.php?pid=5340

orz到了新的字符串hash姿势

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define maxn 200500
#define p 1000000007
using namespace std;
typedef unsigned long long ll;
ll a[maxn],b[maxn],k[maxn];
int c[maxn],d[maxn],t1,t2,cnt,n,t;
char s[maxn];
int main(){
scanf("%d",&t);
k[0]=1;
rep(i,1,20000) k[i]=k[i-1]*p;
while (t--){
scanf("%s",s+1);
n=strlen(s+1);
t1=t2=cnt=b[n+1]=0;
for (int i=1;i<=n;i++) a[i]=a[i-1]*p+s[i];
for (int i=n;i>=1;i--) b[i]=b[i+1]*p+s[i];
for (int i=1;i<=n;i++){
ll h=b[1]-b[i+1]*k[i];
if (h==a[i]) c[++t1]=i;
h=a[n]-a[n-i]*k[i];
if (h==b[n-i+1]) d[++t2]=n-i+1;
}
reverse(c+1,c+1+t1);
int l,r,flag=0;
rep(i,1,t1){
if (flag) break;
rep(j,1,t2){
l=c[i]+1; r=d[j]-1;
if (l>r||cnt>2e6) break;
++cnt;
ll h1=a[r]-a[l-1]*k[r-l+1];
ll h2=b[l]-b[r+1]*k[r-l+1];
if (h1==h2) flag=1;
}
}
if (flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}

时间: 2024-10-28 09:14:39

HDU-5340 Three Palindromes(字符串哈希)的相关文章

hdu 5340 Three Palindromes(字符串处理+ 回文)

hdu 5340 Three Palindromes 问题描述 判断是否能将字符串S分成三段非空回文串. 输入描述 第一行一个整数T,表示数据组数.T \leq 20T≤20 对于每一个组,仅包含一个由小写字母组成的串.1 \leq |S| \leq 200001≤∣S∣≤20000 输出描述 对于每一组,单行输出"Yes" 或 "No". 输入样例 2 abc abaadada 输出样例 Yes No 题目大意:给出一个字符串,判断,是否能将其分成三个不为空的回文

hdu 5340 Three Palindromes 【Manacher】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5340 题意:判断一个字符串能否分为三个回文串 解法:manacher枚举第一第三个,判断第二个. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #inclu

HDU - 5340 Three Palindromes(manacher算法)

http://acm.hdu.edu.cn/showproblem.php?pid=5340 题意 判断是否能将字符串S分成三段非空回文串 分析 manacher预处理出前缀和后缀回文的位置, 枚举第一个回文串和第三个回文串,这样得到第二个回文串的区间,找中点,因为manacher处理后所有的回文串长度都是奇数,然后根据中点的回文半径判断中间部分是否回文即可, 复杂度o(n2).至于n2复杂度为什么能水过去..不是很懂 #include<iostream> #include<cmath&

Hdu 5340 Three Palindromes 最大回文串 Manacher

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 80    Accepted Submission(s): 21 Problem Description Can we divided a given string S into three nonempty palindromes? Input Fir

HDU 5340 Three Palindromes( 折半枚举+Manacher+记录区间 )

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 809    Accepted Submission(s): 240 Problem Description Can we divided a given string S into three nonempty palindromes? Input F

HDU 5340 Three Palindromes(Manacher)

Problem Description: Can we divided a given string S into three nonempty palindromes? Input: First line contains a single integer T≤20 which denotes the number of test cases. For each test case , there is an single line contains a string S which only

HDU 5340——Three Palindromes——————【manacher处理回文串】

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1244    Accepted Submission(s): 415 Problem Description Can we divided a given string S into three nonempty palindromes? Input F

hdu 5340 Three Palindromes

前几晚 BC 的第二题,官方给出的题解是: 然后我结合昨天刚看的 Manacher 算法试着写了下,发现 pre.suf 数组挺难构造的,调试了好久,然后就对中间进行枚举了,复杂度应该是 O(n2) 吧,我第一次交时超时了,以为真的要用什么暴力压位,可是我还不会啊,然后作了一些少许的优化提交本想再 T 一次的,没想到竟然神奇的过了,900+ms 水过,原来还是能卡过的……于是我把更多的细节进行优化,把 *2 和 /2 操作都改为移位运算,再提交时就下降到了 700+ms  :-D 代码如下: 1

HDU 4821 杭州现场赛:每个片段字符串哈希比较

I - String Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4821 Description Given a string S and two integers L and M, we consider a substring of S as "recoverable" if and only if (i) I

HDU 3973 AC&#39;s String 字符串哈希

HDU 3973 通过哈希函数将一个字符串转化为一个整数,通过特定的方式可以使得这个哈希值几乎没有冲突(这就是关键之处,几乎没有视为没有= =!, 其实也可以考虑实现哈希冲突时的处理,只是这道题没必要而已),然后使用线段树维护修改后的哈希值. 因为输入的字符串只有26个,考虑使用一个大于等于26的素数p作为进制,然后将原串转化为一个p进制的数mod 2^63(也相当于自然溢出),然后这个数存入map中,然后使用线段树维护长串区间的哈希值,hash[l, r]表示将区间[l, r]的字符串转化为p