CodeForces327C
来源:互联网 发布:希尔巴布尔美全灭mac 编辑:程序博客网 时间:2024/05/21 15:39
这是今天做的一道快速幂的题,看完题目之后用笔在草稿纸上写写就能分析出来其中的数学公式 ans=(Σpow(2,i)*(pow(2,k*len)-1)/(pow(2,len)-1))%M 但是代码交上去之后一直WA,总是不明白哪里错了,WA了快十次实在不知道怎么改了,于是上网搜了下题解,发现了新大陆!!
在刚才写的公式里面有一个除法求模的运算,之前的代码我就直接相除取模了
ans=(ans+foo(2,i)*((Pkl-1)/(Pl-1)))%M;
实则是不可取的,因为(a/b)%M 并不会等于(a%M)/(b%M)%M
在我看的题解的分析中有说到关于求除法模运算的方法,但是简单带过了,只知道是叫 乘法逆元 于是我就搜索乘法逆元啊,找到了两篇博客:
一篇是数学证明:http://www.cnblogs.com/tiankonguse/archive/2012/08/14/2638949.html
另一篇是求乘法逆元的方法:http://sujinyue.is-programmer.com/posts/38179.html
(这是博客原文,地址在上面,博主若是不希望被转载通知立删)
看了几遍之后大概了解了其中的思路,然后自己验证了一下题目中给定的M=1000000007是素数,那么快速幂求pow(pl,M-2)就可以了,方便简洁。这个方法对快速幂的题目算是升华吧,再也不怕除法模了。
下面是题目代码:
#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<string>#include<iostream>using namespace std;long long M=1000000007;char s[100];long long foo(long long a,long long b){ // printf("pow(%lld,%lld)=",a,b); long long ans=1; a=a%M; while(b) { if(b%2) ans=(ans*a)%M; b/=2; a=(a*a)%M; } // printf("%lld ",ans); return ans;}int main(){ // freopen("in.txt","r",stdin); long long ans; while(scanf("%s",s)!=EOF) { long long len; len=strlen(s); if(s[0]=='-') { for(int i=1;i<len;++i) s[i-1]=s[i]; --len; } long long k; scanf("%lld",&k); long long Pl; Pl=foo(2,len); long long Pkl; Pkl=foo(Pl,k); ans=0; for(long long i=0;i<len;++i) { if(s[i]=='0'||s[i]=='5') { ans=(ans+foo(2,i)*((Pkl-1)/(Pl-1)))%M; } } printf("%lld\n",ans); } return 0;}
0 0
- CodeForces327C
- Codeforces327C Magic Five[组合数学]
- 剑指offer——链表相关问题总结
- HDOJ 题目5289 Assignment(RMQ,技巧)
- Android实战简易教程-第二十八枪(Uri转String型实例)
- HTML5基础16----HTML5框架
- [基本实验] 远程文件包含
- CodeForces327C
- 求包括n个矩形的最小矩形面积模板
- 时间处理
- bootstrap javascript插件中类成员命名之最前面有无$
- 解决VS编译出现Moc'ing文件,系统找不到指定路径问题
- 引脚定义
- B+树索引(转)
- 1.1Qemu 用户态架构
- 求给定M个数组合构成N的最小倍数