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;}


原创粉丝点击