题目
题意: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; }