您的位置:首页 > 其它

[树状数组]uva 5798 Jupiter Atacks!

2012-08-18 21:13 309 查看
H(fi,...,fj)=

Bkfj-k(
modP)

/**uva5798
动态更新fi的值,查询H(fi,...fj)写出f11,f12,...f15;f22,f23,,,f25;....
以最长的f15作参照,设a1...a5分别为f15的第5....1项,sum为a的和,
则f(i,j)=(sum(j)-sum(i-1))/b^(n-j)%p
求和用树状数组,模p用欧拉定理(题目关键2≤B<P≤109andPprime)。trick:注意减法会产生负数
*/
#include<stdio.h>
#include<string.h>

#defineN100001
#definelowbit(i)(i)&(-i)
__int64B
,f
,A
;
intn;
voidadd(inti,__int64c)
{
for(;i<=n;i+=lowbit(i))
A[i]+=c;
}
__int64sum(inti)
{
__int64ans=0LL;
for(;i>0;i-=lowbit(i))
ans+=A[i];
returnans;
}
__int64fpow(__int64a,__int64b,__int64p)
{
__int64ans=1LL;
while(b)
{
if(b&1)
ans=ans*a%p;
b>>=1;
a=a*a%p;
}
returnans;
}
intmain()
{
B[0]=1LL;
intq,i,j;
__int64b,p;
charask[4];
while(scanf("%I64d%I64d%d%d",&b,&p,&n,&q)!=EOF&&b)
{
memset(A,0,sizeof(A));
memset(f,0,sizeof(f));
for(i=1;i<n;++i)
B[i]=B[i-1]*b%p;
while(q--)
{
scanf("%s%d%d",ask,&i,&j);
if(ask[0]=='H')
{
printf("%I64d\n",(sum(j)-sum(i-1)+p)%p*fpow(B[n-j],p-2,p)%p);
continue;
}
add(i,(1LL*j-f[i]+p)%p*B[n-i]%p);
f[i]=j;
}
puts("-");
}
return0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: