ABC 331 F - Palindrome Query(字符串哈希,树状数组)

字符串哈希

[OI-Wiki](字符串哈希 - OI Wiki (oi-wiki.org))

分为两种哈希方式:以左为高位以右为高位

如果只是快速查询每个字串的哈希值,用以左为高位比较简单,即

\[Hash[l...r]=Hash[1...r]-Hash[1...(l-1)]\times base^{r-l+1} \]

但是如果有修改操作,需要将每一位的 Hash 值存到数据结构里(例如线段树、树状数组),那么采取以右为高位可以直接通过区间求和来获取 1...x 的Hash值。但是要注意求 [l,r] 的Hash值时需要再除以\(base^{l-1}\)

判断回文

将字符串正着哈希一遍,逆着哈希一遍,若两个Hash值相等,则回文。

具体实现可以开两个树状数组。

代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<ctime>
#include<stack>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!(c>='0'&&c<='9')) {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=1000005;
const long long mod=998244353;
int n,q;
char s[maxn];
long long d[maxn],d2[maxn],mi[maxn];
inline int lowbit(int x){
	return x&(-x);
}
void add(int x,long long v){
	for(int i=x;i<=n;i+=lowbit(i)) d[i]=(d[i]+v)%mod;
}
void add2(int x,long long v){
	for(int i=x;i<=n;i+=lowbit(i)) d2[i]=(d2[i]+v)%mod;
}
long long query(int x){
	long long res=0;
	for(int i=x;i>=1;i-=lowbit(i)) res+=d[i];
	return res%mod;
}
long long query2(int x){
	long long res=0;
	for(int i=x;i>=1;i-=lowbit(i)) res+=d2[i];
	return res%mod;
}
long long has(int l,int r){
	return (query(r)-query(l-1)+mod)%mod*mi[n-l]%mod;
}
long long has2(int l,int r){
	return (query2(r)-query2(l-1)+mod)%mod*mi[n-l]%mod;
}
int main()
{
	n=read(),q=read();
	mi[0]=1;
	for(int i=1;i<=n;i++){
		mi[i]=mi[i-1]*27%mod;
	}
	for(int i=1;i<=n;i++){
		s[i]=getchar();
		while(s[i]<'a'||s[i]>'z') s[i]=getchar();
		add(i,mi[i-1]*(s[i]-'a'+1)%mod);
		add2(n-i+1,mi[n-i]*(s[i]-'a'+1)%mod);
	}
	while(q--){
		int tp=read();
		if(tp==1){
			int x=read();
			char c=getchar();
			add(x,mi[x-1]*(c-s[x]+mod)%mod);
			add2(n-x+1,mi[n-x]*(c-s[x]+mod)%mod);
			s[x]=c;
		}else{
			int x=read(),y=read();
			if(has(x,y)==has2(n-y+1,n-x+1)) puts("Yes");
			else puts("No");
		}
	}
    return 0;
}
posted @ 2023-12-03 14:17  尹昱钦  阅读(80)  评论(0编辑  收藏  举报