Hash求调
查看原帖
Hash求调
1014573
sevenki楼主2024/1/17 14:06

思路:用线段树维护正序、倒序的哈希值。

ac15 wa10

#include <bits/stdc++.h>
#define MAXN 1000006
#define ull unsigned long long
#define int ull
using namespace std;
const int mod[4] = {20090723,998244353,1000000007,1000000009};
const int base = 131;
char c[MAXN];
int pb[4][MAXN];
int n,q;
#define ls (p<<1)
#define rs (p<<1|1)
struct node{
	int l,r;
	int Lsum[4],Rsum[4];
}tr[4*MAXN];
void pushUp(int p){
	int Lsiz = tr[ls].r-tr[ls].l+1;
	int Rsiz = tr[rs].r-tr[rs].l+1;
	for(int i=0;i<4;i++){
		tr[p].Lsum[i]=(1ll*tr[ls].Lsum[i]*pb[i][Rsiz]%mod[i]+tr[rs].Lsum[i])%mod[i];
		tr[p].Rsum[i]=(1ll*tr[rs].Rsum[i]*pb[i][Lsiz]%mod[i]+tr[ls].Rsum[i])%mod[i];
	}
}
void build(int l,int r,int p){
	tr[p].l=l,tr[p].r=r;
	if(l==r){
		tr[p].Lsum[0]=tr[p].Rsum[0]=
		tr[p].Lsum[1]=tr[p].Rsum[1]=
		tr[p].Lsum[2]=tr[p].Rsum[2]=
		tr[p].Lsum[3]=tr[p].Rsum[3]=c[l]-'a';return;
	}
	int mid = (l+r)/2;
	build(l,mid,ls);build(mid+1,r,rs);pushUp(p);
}
void modify(int x,int c,int p){
	if(tr[p].l==tr[p].r){
		tr[p].Lsum[0]=tr[p].Rsum[0]=
		tr[p].Lsum[1]=tr[p].Rsum[1]=
		tr[p].Lsum[2]=tr[p].Rsum[2]=
		tr[p].Lsum[3]=tr[p].Rsum[3]=c;return;
	}
	if(x<=tr[ls].r)modify(x,c,ls);
	else modify(x,c,rs);
	pushUp(p);
}
int queryL(int l,int r,int mdt,int p=1){
	if(l<=tr[p].l&&r>=tr[p].r)return tr[p].Lsum[mdt];
	if(l<=tr[ls].r&&r>=tr[rs].l){
		int Rsiz = r-tr[rs].l+1;
		return (queryL(l,r,mdt,ls)*pb[mdt][Rsiz]%mod[mdt]+queryL(l,r,mdt,rs))%mod[mdt];
	}
	if(l<=tr[ls].r){
		return queryL(l,r,mdt,ls);
	}else return queryL(l,r,mdt,rs);
}
int queryR(int l,int r,int mdt,int p=1){
	if(l<=tr[p].l&&r>=tr[p].r)return tr[p].Rsum[mdt];
	if(l<=tr[ls].r&&r>=tr[rs].l){
		int Lsiz = tr[ls].r-l+1;
		return (queryR(l,r,mdt,rs)*pb[mdt][Lsiz]%mod[mdt]+queryR(l,r,mdt,ls))%mod[mdt];
	}
	if(l<=tr[ls].r){
		return queryR(l,r,mdt,ls);
	}else return queryR(l,r,mdt,rs);
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>q;
	cin>>(c+1);
	pb[0][0]=pb[1][0]=1;
	pb[2][0]=pb[3][0]=1;
	for(int j=0;j<4;j++)
	for(int i=1;i<MAXN;i++)pb[j][i]=pb[j][i-1]*base%mod[j];
	build(1,n,1);
	while(q--){
		int op;cin>>op;
		if(op==1){
			int x;char C;cin>>x>>C;C-='a';
			//cerr<<6;
			modify(x,C,1);
		}else{
			int l,r;cin>>l>>r;//cerr<<7;
			//cerr<<queryL(l,r)<<" "<<queryR(l,r)<<"\n";
			bool f = 1;
			for(int i=0;i<4;i++)f&=(queryL(l,r,i)==queryR(l,r,i));
			cout<<(f ? "Yes\n" : "No\n");
		}
	}
	return 0;
}
2024/1/17 14:06
加载中...