acdream 1019 Palindrome(哈希)

题目链接:http://www.acdream.net/problem.php?id=1019

题意:给定一个字符串str,两个操作:

(1)C a x 将位置a上的字母改为x

(2)Q a b 询问str[a,……b]是不是回文串。

思路:用哈希存储每个子串。具体方法是用上树状数组进行快速统计。

#include <iostream>

#include <stdio.h>

#include <string.h>

#define i64 unsigned long long

using namespace std;



const int MAX=1000005;

i64 bit[MAX],s[2][MAX];

char str[MAX];

int n;



void init()

{

    int i;

    bit[0]=1;

    for(i=1;i<MAX;i++) bit[i]=bit[i-1]*107;

}



void Add(int x,i64 det,int p)

{

    while(x<MAX)

    {

        s[p][x]+=det;

        x+=x&(-x);

    }

}



i64 get(int x,int p)

{

    i64 ans=0;

    while(x)

    {

        ans+=s[p][x];

        x-=x&(-x);

    }

    return ans;

}



void deal()

{

    char cmd[5];

    int a,b,Q;

    i64 x,y;

    for(scanf("%d",&Q);Q--;)

    {

        scanf("%s",cmd);

        if(cmd[0]=='C')

        {

            scanf("%d%s",&a,cmd);

            Add(a,(cmd[0]-str[a])*bit[a],0);

            Add(n+1-a,(cmd[0]-str[a])*bit[n+1-a],1);

            str[a]=cmd[0];

        }

        else

        {

            scanf("%d%d",&a,&b);

            x=(get(b,0)-get(a-1,0))*bit[MAX-a];

            a=n+1-a;

            b=n+1-b;

            y=(get(a,1)-get(b-1,1))*bit[MAX-b];

            if(x==y) puts("yes");

            else puts("no");

        }

    }

}



int main()

{

    init();

    while(scanf("%s",str+1)!=-1)

    {

        n=strlen(str+1);

        memset(s,0,sizeof(s));

        int i;

        for(i=1;i<=n;i++)

        {

            Add(i,str[i]*bit[i],0);

            Add(n+1-i,str[i]*bit[n+1-i],1);

        }

        deal();

    }

    return 0;

}

  

你可能感兴趣的:(ROM)