1345: PIPI的字符串问题Ⅲ

1345: PIPI的字符串问题Ⅲ

题目描述

PIPI双来考查大家字符串处理的能力啦。
给定一个字符串S,以及q次询问。
每次询问给出两个正整数L,R,你需要回答S[L~R]是否为回文串。

输入

第一行给出字符串S,|S|<=1e6. 保证字符串仅由小写字母构成。
第二行给出询问次数q,q<=1e6.
接下来每行给出两个整数L,R,1<=L,R<=|S|.

输出

对于每个询问,若字符串S中[L,R]为回文串,输出YES,否则输出NO。

样例输入

abccba
5
1 6
2 5
3 4
1 3
1 1

样例输出

YES
YES
YES
NO
YES

思路

常规的判别回文串的方法时间复杂度为 o(n),此处有多次询问,肯定会超时。所以使用字符串哈希和双向哈希,判别正向和逆向字符串的哈希值是否相等,若相等则为回文串,判别字符串是否为回文串的时间复杂度为 o(1)。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef unsigned long long ull;
char s[N];
ull Hash_f[N], Hash_r[N], base = 2333;
ull p[N];

int main()
{
	scanf("%s", s);
	int lens = strlen(s);
	//Hash 正向 
	for(int i = 1; i <= lens; i++) 
		Hash_f[i] = Hash_f[i - 1] * base + s[i - 1];
	// 反向哈希要多体会
	for(int i = lens; i >= 1; i--)
		Hash_r[i - 1] = Hash_r[i] * base + s[i - 1];
//	for(int i = 0; i <= lens; i++)
//		cout<<Hash_f[i]<<' ';
//	cout<<endl;
//	for(int i = 0; i <= lens; i++)
//		cout<<Hash_r[i]<<' ';
//	cout<<endl;
	//获得基数的 k 次方
	p[0] = 1;
	for(int i = 1; i <= lens; i++)	p[i] = p[i - 1] * base;
	int q;
	scanf("%d", &q);
	int l, r;
	while(q--)
	{
		scanf("%d%d", &l, &r);
		if(Hash_f[r] - Hash_f[l - 1] * p[r - l + 1] == Hash_r[l - 1] - Hash_r[r] * p[r - l + 1])
			printf("YES\n");
		else
			printf("NO\n");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值