Acdream 1019 Palindrome 树状数组 + 字符串hash

来源:互联网 发布:剑灵男力士捏脸数据 编辑:程序博客网 时间:2024/06/05 03:15

Acdream 1019 Palindrome

这道题也算是卡了很久了 -  -

最近才发现有些细节没考虑到。

思路是用两颗树状数组维护HASH前缀和 (一正一反两个反向)

坑1:线段树不是MLE就是TLE

坑2:在查出两个串后  多项式的幂是不一样的(s[3] * 1331 ^ 3 + s[4] * 1331 ^ 4 + s[5] * 1331 ^ 5 和 s[3] * 1331 ^ 2+s[4] * 1331 ^ 1 + s[5] * 1331 ^ 0),

不能用除法统一幂。因为这种HASH的原理是unsiged long long 溢出  相当于取余了。

这里就要用逆元  然而我并不会。所以我们把幂小的乘以一个数让他的幂变大 -  -


/** this code is made by Hivoodoo* Problem: 1019* Verdict: Accepted* Submission Date: 2015-10-03 13:03:06* Time: 1336MS* Memory: 41716KB*/#include <bits/stdc++.h>using namespace std;typedef unsigned long long ULL;const int MAXN = 1e6+10;ULL xl[MAXN];//适用于正整数template <class T>inline void scan_d(T &ret){    char c;    ret=0;    while((c=getchar())<'0'||c>'9');    while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();}int n;struct BIT{    inline int lowbit(int x)    {        return x&-x;    }    ULL a[MAXN],b[MAXN];    void init()    {        for(int i=0; i<=n; i++)            a[i]=b[i]=0;    }    void add(int pos, ULL v)    {        for(int i=pos; i<=n; i+=lowbit(i))            a[i] += v;    }    ULL sum(int pos)    {        ULL ret = 0;        for (int i=pos; i>0; i-=lowbit(i))            ret += a[i];        return ret;    }    void update(int pos,ULL v)    {        pos++;        if(b[pos])            add(pos,-b[pos]);        add(pos,b[pos]=v);    }    ULL query(int a,int b)    {        a,b++;        return sum(b)-sum(a);    }} soul[2];char s[MAXN];int main(){    int m;    xl[0]=1;    for(int i=1; i<MAXN-1; i++)        xl[i]=xl[i-1]*13331;    while(scanf("%s",s)!=EOF)    {        n=strlen(s);        soul[0].init();        soul[1].init();        scan_d(m);        for(int i=0,j=n-1; i<n; i++,j--)            soul[0].update(i,xl[i]*s[i]),soul[1].update(j,xl[j]*s[i]);        while(m--)        {            int a,b;            scanf("%s",s);            if(s[0]=='Q')            {                scan_d(a);                scan_d(b);                if(a>b)                    swap(a,b);                a--,b--;                ULL ra=soul[0].query(a,b);                ULL rb=soul[1].query(n-b-1,n-a-1);                int d=n-b-1-a;                if(d>0)                    ra*=xl[d];                else                    rb*=xl[-d];                if(ra==rb)                    puts("yes");                else                    puts("no");            }            else            {                scan_d(a);                scanf("%s",s);                a--;                soul[0].update(a,s[0]*xl[a]);                soul[1].update(n-a-1,s[0]*xl[n-a-1]);            }        }    }    return 0;}


0 0
原创粉丝点击