快速幂详解——2017中国大学生程序设计竞赛
来源:互联网 发布:淘宝店铺名字会重名吗 编辑:程序博客网 时间:2024/06/05 02:10
Easy Summation
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/131072K (Java/Other)
Total Submission(s) : 6 Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
You are encountered with a traditional problem concerning the sums of powers.
Given two integersn and k . Let f(i)=ik , please evaluate the sum f(1)+f(2)+...+f(n) . The problem is simple as it looks, apart from the value of n in this question is quite large.
Can you figure the answer out? Since the answer may be too large, please output the answer modulo109+7 .
Given two integers
Can you figure the answer out? Since the answer may be too large, please output the answer modulo
Input
The first line of the input contains an integer T(1≤T≤20) , denoting the number of test cases.
Each of the followingT lines contains two integers n(1≤n≤10000) and k(0≤k≤5) .
Each of the following
Output
For each test case, print a single line containing an integer modulo109+7 .
Sample Input
32 54 24 1
Sample Output
333010
Source
2017中国大学生程序设计竞赛 - 女生专场
思路:
刚刚看到这道题觉得就是用大数相加的方法,先分别求出f(1)...f(n),在把这些数加起来。最后调试完成后发现超时,后来在网上看到别人40行代码,才知道了快速幂,确实快很多,安利一下这种解法。
先上代码
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<cstdlib>using namespace std;long long pow2(long long a,int b)//快速幂 位运算版{ long long r=1,base=a; while(b) { if(b&1) r=(r*base)%1000000007; base=(base*base)%1000000007; b>>=1; } return r;}int main(){ int m; cin>>m; while(m--) { int n,k; cin>>n>>k; long long sum=0; for(int i=1;i<=n;i++) { sum+=pow2(i,k); sum=sum%1000000007;//1000000007 } cout<<sum<<endl; } return 0;}
快速幂的思想:
首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn),快了好多好多。它的原理如下:
假设我们要求a^b,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时
a^11=a^(2^0+2^1+2^3)
11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 a^(2^0)*a^(2^1)*a^(2^3)
,看出来快的多了吧原来算11次,现在算三次,但是这三项貌似不好求的样子....不急,下面会有详细解释。
由于是二进制,很自然地想到用位运算这个强大的工具: & 和 >>
&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。
>>运算比较单纯,二进制去掉最后一位,不多说了,先放代码再解释。
1 int poww(int a,int b){ 2 int ans=1,base=a; 3 while(b!=0){ 4 if(b&1!=0) 5 ans*=base; 6 base*=base; 7 b>>=1; 8 } 9 return ans;10 }
代码很短,死记也可行,但最好还是理解一下吧,其实也很好理解,以b==11为例,b=>1011,二进制从右向左算,但乘出来的顺序是 a^(2^0)*a^(2^1)*a^(2^3),是从左向右的。我们不断的让base*=base目的即是累乘,以便随时对ans做出贡献。
其中要理解base*=base这一步,看:::base*base==base^2,下一步再乘,就是base^2*base^2==base^4,然后同理 base^4*base4=base^8,,,,,see?是不是做到了base-->base^2-->base^4-->base^8-->base^16-->base^32.......指数正是 2^i 啊,再看上 面的例子,a¹¹= a^(2^0)*a^(2^1)*a^(2^3),这三项是不是完美解决了,,嗯,快速幂就是这样。
顺便啰嗦一句,由于指数函数是爆炸增长的函数,所以很有可能会爆掉int的范围,根据题意决定是用 long long啊还是unsigned int啊还是mod某个数啊自己看着办。
1 0
- 快速幂详解——2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 【HDU6150 2017中国大学生程序设计竞赛
- 【HDU6152 2017中国大学生程序设计竞赛
- 抽象类和接口(转)
- Linux yum 保留安装包
- Unity A*寻路详解
- Nginx socket.io 反向代理配置
- mybaits中查询中对象中存在对象(可能是单一对象,可能是集合)
- 快速幂详解——2017中国大学生程序设计竞赛
- 代码重构笔记
- 【Oracle sql基础】trunc()函数的用法
- 分针网—IT教育: 关于Node.js的__dirname,__filename,process.cwd(),./文件路径的一些坑
- QT之ComboBox角色使用QAbstractListModel
- VS2013无法加载解决方案中的项目
- js:显示倒计时之后跳转另外的页面
- FileItem类的常用方法:
- 修改ios.js