URAL 1989 Subpalindromes(字符串HASH&线段树单点更新)
来源:互联网 发布:国产碳纤维 知乎 编辑:程序博客网 时间:2024/05/20 03:42
题意:给你长度为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;}
- URAL 1989 Subpalindromes(字符串HASH&线段树单点更新)
- URAL 1989 Subpalindromes(线段树单点修改+字符串hash)
- URAL 1989 Subpalindromes(回文串 线段树 多项式hash)
- bnu36907 Subpalindromes 字符串hash+线段树
- URAL 1989 Subpalindromes(多项式哈希+线段树)
- URAL 1989 Subpalindromes(多项式哈希+线段树)
- Ural 1028. Stars 线段树单点更新
- URAL 1989 Subpalindromes
- URAL 1989 Subpalindromes
- URAL 1989 Subpalindromes 思路
- 线段树(单点更新)
- 线段树(单点更新)
- 线段树(单点更新+区间更新)
- hdu 3973 AC's String(字符串hash+线段树单点修改)
- 线段树 单点更新
- 线段树单点更新
- 线段树 单点更新
- 单点更新线段树
- 位置无关代码(PIC)的思考
- 前缀树
- Java SE、Java EE、Java ME三者的区别
- Maclean对Oracle社区的一点点小建设
- RMAN 备份与恢复 实例 【偶像大神-dave老师】
- URAL 1989 Subpalindromes(字符串HASH&线段树单点更新)
- 如何将cocos2d-x项目打包成一个.exe
- FZU-单词问题
- IOS绘图详解
- MAC OX 10.8 环境下运行TLD算法(MATLAB版)
- 深度分析NandFlash —控制器参数TACLS、TWRPH0和TWRPH1的确定(TQ2440_K9F2G08U0A)
- 《代码大全第二版》学习笔记(三)
- 分类的使用 对NSString的扩展
- Cookie 的setPath 方法的误解