UVAlive5798 Jupiter Atacks!

题目

题意:n个数,两种操作,E a b 第a个数等于b,H a b求区间[a,b]的hash值,hash函数为将区间[a,b]转一个B进制的数模mod。

题解:单点更新,区间查询,预处理出来B的幂次方。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100005

int n,m,mod;
long long ba,data[MAXN<<2],po[MAXN];
void insert(int p,int L,int R,int pos,int val)
{
    if (L==R)
    {
        data[p]=val;
        return;
    }
    int mid=(L+R)>>1;
    if (pos<=mid) insert(p<<1,L,mid,pos,val);
    else insert(p<<1|1,mid+1,R,pos,val);
    data[p]=(data[p<<1]*po[R-mid]%mod+data[p<<1|1])%mod;
}
long long cal(int p,int L,int R,int l,int r)
{
    if (L==l&&R==r)
        return data[p];
    int mid=(L+R)>>1;
    if (r<=mid) return cal(p<<1,L,mid,l,r);
    else if (l>mid) return cal(p<<1|1,mid+1,R,l,r);
    else return (cal(p<<1,L,mid,l,mid)*po[r-mid]%mod+cal(p<<1|1,mid+1,R,mid+1,r))%mod;
}
int main()
{
    //freopen("/home/moor/Code/input","r",stdin);
    int l,r;
    char st[5];
    while (scanf("%lld%d%d%d",&ba,&mod,&n,&m)!=-1)
    {
        if (!ba&&!mod) break;
        memset(data,0,sizeof(data));
        po[0]=1;
        for (int i=1;i<=n;i++) po[i]=po[i-1]*ba%mod;
        while (m--)
        {
            scanf("%s%d%d",st,&l,&r);
            if (st[0]=='E')
                insert(1,1,n,l,r%mod);
            else printf("%lld\n",cal(1,1,n,l,r));
        }
        printf("-\n");
    }
    return 0;
}


你可能感兴趣的:(UVAlive5798 Jupiter Atacks!)