题意:给你长度为N的字符串,有M个操作,操作有两种类型(1)“change i a”,表示将第i个字符变成a,(2)“palindrome? j k”,询问[j,k]的字符串是否构成回文串。
从0到N-1HASH一次,到从N-1到0HAsH一次,判断的话,直接判断两次HASH后的结果是否相同,保险相见,用了双HASH。操作(1)的话,直接用线段树单点更新就可以搞定。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
typedef unsigned uint;
typedef pair<uint,uint> PII;
const int N=1e5+5;
const uint mult1=127;
const uint mult2=131;
int A[N];
uint pow1[N],pow2[N];
struct Segtree
{
bool type;
uint key1[N*4],key2[N*4];
void PushUp(int ind,int lft,int rht)
{
int mid=MID(lft,rht);
if(type==0)
{
int len=mid-lft+1;
key1[ind]=key1[LL(ind)]+key1[RR(ind)]*pow1[len];
key2[ind]=key2[LL(ind)]+key2[RR(ind)]*pow2[len];
}
else
{
int len=rht-(mid+1)+1;
key1[ind]=key1[LL(ind)]*pow1[len]+key1[RR(ind)];
key2[ind]=key2[LL(ind)]*pow2[len]+key2[RR(ind)];
}
}
void build(int lft,int rht,int ind)
{
if(lft==rht) key1[ind]=key2[ind]=A[lft];
else
{
int mid=MID(lft,rht);
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
PushUp(ind,lft,rht);
}
}
void updata(int pos,int valu,int lft,int rht,int ind)
{
if(lft==rht) key1[ind]=key2[ind]=valu;
else
{
int mid=MID(lft,rht);
if(pos<=mid) updata(pos,valu,lft,mid,LL(ind));
else updata(pos,valu,mid+1,rht,RR(ind));
PushUp(ind,lft,rht);
}
}
PII query(int st,int ed,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed) return make_pair(key1[ind],key2[ind]);
else
{
int mid=MID(lft,rht);
if(ed<=mid) return query(st,ed,lft,mid,LL(ind));
else if(st>mid) return query(st,ed,mid+1,rht,RR(ind));
else
{
PII tmp1=query(st,mid,lft,mid,LL(ind));
PII tmp2=query(mid+1,ed,mid+1,rht,RR(ind));
PII ans;
if(type==0)
{
int len=mid-st+1;
ans.first=tmp1.first+tmp2.first*pow1[len];
ans.second=tmp1.second+tmp2.second*pow2[len];
}
else
{
int len=ed-(mid+1)+1;
ans.first=tmp1.first*pow1[len]+tmp2.first;
ans.second=tmp1.second*pow2[len]+tmp2.second;
}
return ans;
}
}
}
}seg[2];
char str[N];
int main()
{
// freopen("in.txt","r",stdin);
pow1[0]=pow2[0]=1;
for(int i=1;i<N;i++)
{
pow1[i]=pow1[i-1]*mult1;
pow2[i]=pow2[i-1]*mult2;
}
while(scanf("%s", str)!=EOF)
{
int len=(int)strlen(str);
for(int i=0;i<len;i++) A[i]=(str[i]-'a');
seg[0].type=0; seg[1].type=1;
seg[0].build(0,len-1,1);
seg[1].build(0,len-1,1);
int m; scanf("%d",&m);
while(m--)
{
char op[100]; scanf("%s",op);
if(op[0]=='p')
{
int st,ed; scanf("%d%d",&st,&ed);
st--;ed--;
int st1,ed1,st2,ed2;
if((ed-st+1)&1)
{
st1=st; ed1=MID(st,ed);
st2=MID(st,ed); ed2=ed;
}
else
{
st1=st; ed1=MID(st,ed);
st2=MID(st,ed)+1; ed2=ed;
}
PII tmp1=seg[0].query(st1,ed1,0,len-1,1);
PII tmp2=seg[1].query(st2,ed2,0,len-1,1);
if(tmp1.first==tmp2.first&&tmp1.second==tmp2.second) puts("Yes");
else puts("No");
}
else
{
int pos; char chr[10];
scanf("%d%s",&pos,chr);
pos--;
seg[0].updata(pos,chr[0]-'a',0,len-1,1);
seg[1].updata(pos,chr[0]-'a',0,len-1,1);
}
}
}
return 0;
}