版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37129433/article/details/82431215
题 意:给你一个长度为n的字符串,m次操作,palindrome? l,r。表示询问[l,r]是否是回文串,change x ch 把第x个字符转化成ch。
数据范围:
5<=n,m<=1e5
1 <= l<= r <= n
输入样例:
abcda
5
palindrome? 1 5
palindrome? 1 1
change 4 b
palindrome? 1 5
palindrome? 2 4
输出样例:
No
Yes
Yes
Yes
思 路:思路是分析出来的,有些是一眼题,有些是需要分析的。首先看数据范围,1e5,又是两种操作,很容易就应该想到是线段树,又是回文串啥的,回文串不就是最简单的hash。Hash是一种思想,那是一种可以BDRHHash避免冲突非常高的一种写法。直接转化成进制也可以是一种Hash 的思想。
收 获:要去分析题目,hash也转化成了一种思想。Hash 那个seed能奇数最好奇数。(lll¬ω¬)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef unsigned long long ull;
const int maxn = 1e5+5;
ull sum1[maxn<<2],sum2[maxn<<2];
ull f[maxn];
char s[maxn];
int n,m;
void PushUp(int rt){
sum1[rt] = sum1[rt<<1] + sum1[rt<<1|1];
sum2[rt] = sum2[rt<<1] + sum2[rt<<1|1];
}
void build(int l,int r,int rt){
if(l == r){
sum1[rt] = ull(s[l]-'a'+1)*f[l-1]; //这也是一种很好的思路
sum2[rt] = ull(s[l]-'a'+1)*f[n-l];
return ;
}
int m = (l+r)/2;
build(lson);
build(rson);
PushUp(rt);
return;
}
ull query(int L,int R,int flag,int l,int r,int rt){
if(L<=l && r<=R){
if(flag == 1) return sum1[rt];
else return sum2[rt];
}
int m = (l+r)/2;
ull ans = 0;
if(L<=m) ans+=query(L,R,flag,lson);
if(R>m ) ans+=query(L,R,flag,rson);
return ans;
}
void update(int pos,char x,int l,int r,int rt){
if(l == r){
sum1[rt] = (x-'a'+1)*f[l-1];
sum2[rt] = (x-'a'+1)*f[n-l];
return;
}
int m = (l+r)/2;
if(pos<=m) update(pos,x,lson);
else update(pos,x,rson);
PushUp(rt);
}
int main() {
scanf("%s",s+1);
scanf("%d",&m);
int l,r;
char str[100];
n = strlen(s+1);
f[0] = 1;
for(int i=1;i<=n;i++){
f[i] = f[i-1]*13131;
}
build(1,n,1);
while(m--){
scanf("%s",str);
if(str[0] == 'p'){
scanf("%d %d",&l,&r);
ull ans1,ans2;
ans1 = query(l,r,1,1,n,1);
ans2 = query(l,r,2,1,n,1);
int temp1 = l-1;
int temp2 = n-r;
// printf("%d %d %llu %llu\n",temp1,temp2,ans1,ans2);
if(temp1 < temp2){ //这个地方自己去举一个简单的例子就好了。
ans1 *= f[temp2-temp1];
}else if(temp1>temp2){
ans2 *= f[temp1-temp2];
}
if(ans1 == ans2){
printf("Yes\n");
}else{
printf("No\n");
}
}else{
char ch[10];
scanf("%d%s",&l,ch);
update(l,ch[0],1,n,1);
}
}
return 0;
}
/*
abcba
5
palindrome? 1 3
palindrome? 2 4
palindrome? 3 3
*/