题意:给你长度为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; }