URAL 1989 Subpalindromes(字符串HASH&线段树单点更新)

题意:给你长度为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&线段树单点更新))