uvalive5798(树状数组)
来源:互联网 发布:双十一数据图 编辑:程序博客网 时间:2024/06/05 23:00
题意:
单点更新,区间求和,求和操作和普通的求和不一样,如果我们要求2~5的和,sum=1*f[5]+b*f[4]+b*b*f[3]+b*b*b*f[2],输出每个询问操作的答案,同时答案要模p。
思路:
我们可以在操作的时候直接给每个位置的数字成上b的多少次幂,例如如果是五个数字,我们插入f1时,我们不插入f1,而是插入f1*b*b*b*b,插入f2时,我们插入f2*b*b*b,这样,询问的时候我们就可以直接区间求和,再除以一个b的多少次幂。同时要注意,除法取模要求逆元,计算b的次幂的时候要用快速幂,被红书的快速幂坑了。。。它的那个取模不够彻底。
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cstdlib>#include<cmath>using namespace std;long long _b,_p,_l,_n;long long pow_mod(long long a,long long i,long long n){if(i==0)return 1%n;int temp=pow_mod(a%n,i>>1,n)%n;temp=(temp%n*temp%n)%n;if(i&1)temp=(long long)temp*a%n;return temp;}long long extend_gcd(long long a,long long b,long long &x,long long &y) { if(a==0&&b==0) return -1;//无最大公约数 if(b==0){x=1;y=0;return a;} long long d=extend_gcd(b,a%b,y,x); y-=a/b*x; return d; } long long mod_reverse(long long a,long long n) { long long x,y; long long d=extend_gcd(a,n,x,y); if(d==1) return (x%n+n)%n; else return -1; } const long long maxn=100005;long long Tree[maxn+10];inline long long lowbit(long long x){return x&(-x);}void add(long long x,long long value){for(long long i=x;i<=maxn;i+=lowbit(i)){Tree[i]+=value;Tree[i]%=_p;}}long long get(long long x){long long sum=0;for(long long i=x;i;i-=lowbit(i)){sum+=Tree[i];sum%=_p;}return (sum);}int main(){//cout << pow_mod(2, 10, 1000000) << endl;while(scanf("%lld%lld%lld%lld",&_b,&_p,&_l,&_n)!=EOF){memset(Tree,0,sizeof Tree);if(!_b&&!_p&&!_l&&!_n)return 0;for(long long i=1;i<=_n;i++){char s[3];long long x,y;scanf("%s%lld%lld",s,&x,&y);if(s[0]=='E'){y%=_p;long long tmp=(get(x)-get(x-1)+_p)%_p;//printf("tmp=%lld\n",tmp);//printf("lala=%lld\n",(y*pow_mod(_b,_l-x,_p)%_p-tmp+_p)%_p);add(x,(y*pow_mod(_b%_p,_l-x,_p)%_p-tmp+_p)%_p);//add(x,y);}else{long long ans=(get(y)%_p-get(x-1)%_p+_p)%_p;//printf("---------------- %lld %lld \n",get(y),get(x-1));//printf("chu=%lld\n",pow_mod(_b%_p,_l-y,_p));//printf("ans=%lld\n",ans);ans%=_p;long long ni=mod_reverse(pow_mod(_b%_p,_l-y,_p),_p);ni%=_p;ans*=ni;printf("%lld\n",ans%_p);}}printf("-\n");}return 0;}
0 0
- uvalive5798(树状数组)
- UVAlive5798 Jupiter Atacks!
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- oracle wm_concat函数,用于列转行,逗号分隔
- 记录一些易忘的属性(translucent,edgesForExtendedLayout,automaticallyAdjustsScrollViewInsets)
- Bone Collector II
- poj 1047 模拟(含大数乘法)循环数
- hdu 5294 Tricks Device (最短路+最大流)
- uvalive5798(树状数组)
- android mk脚本的编写
- VC 读写注册表
- 3.4 summary
- spring mvc中的@RequestMapping的用法
- C# UDP(Socket)异步传输文件
- 导致实例逐出的五大问题
- Lightoj 1094 - Farthest Nodes in a Tree 【树的直径裸题】
- iOS开发 -- UIButton