快速幂总结

快速幂总结

快速幂这个东西比较好理解,但实现起来到不老好办,记了几次老是忘,今天把它系统的总结一下防止忘记。

  首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn),快了好多好多。它的原理如下:

  假设我们要求a^b,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时

 a11=a(2^0+2^1+2^3)
11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 a2^0*a2^1*a2^3,也就是a1*a2*a8 
,看出来快的多了吧原来算11次,现在算三次,但是这三项貌似不好求的样子....不急,下面会有详细解释。                                                                                             
 
 
由于是二进制,很自然地想到用位运算这个强大的工具:&和>>    
 
&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。
 
>>运算比较单纯,二进制去掉最后一位,不多说了,先放代码再解释。
 
 
复制代码
 1 int poww(int a,int b){//求a的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==base2,下一步再乘,就是base2*base2==base4,然后同理  base4*base4=base8,由此可以做到base-->base2-->base4-->base8-->base16-->base32.......指数正是 2^i ,再看上面的例子,a¹¹= a1*a2*a8,这三项就可以完美解决了,快速幂就是这样。

  顺便啰嗦一句,由于指数函数是爆炸增长的函数,所以很有可能会爆掉int的范围,根据题意选择 long long还是mod某个数自己看着办。

  矩阵快速幂也是这个道理,下面放一个求斐波那契数列的矩阵快速幂模板

复制代码
 1 #include<iostream>2 #include<cstdio>3 #include<cstring>4 #include<cmath>5 #include<algorithm>6 using namespace std;7 const int mod = 10000;8 const int maxn = 35;9 int N;
10 struct Matrix {
11     int mat[maxn][maxn];
12     int x, y;
13     Matrix() {
14         memset(mat, 0, sizeof(mat));
15         for (int i = 1; i <= maxn - 5; i++) mat[i][i] = 1;
16     }
17 };
18 inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
19     memset(c.mat, 0, sizeof(c.mat));
20     c.x = a.x; c.y = b.y;
21     for (int i = 1; i <= c.x; i++) {
22         for (int j = 1; j <= c.y; j++) {
23             for (int k = 1; k <= a.y; k++) {
24                 c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
25                 c.mat[i][j] %= mod;
26             }
27         }
28     }
29     return;
30 }
31 inline void mat_pow(Matrix &a, int z) {
32     Matrix ans, base = a;
33     ans.x = a.x; ans.y = a.y;
34     while (z) {
35         if (z & 1 == 1) mat_mul(ans, base, ans);
36         mat_mul(base, base, base);
37         z >>= 1;
38     }
39     a = ans;
40 }
41 int main() {
42     while (cin >> N) {
43         switch (N){
44             case -1: return 0;
45             case 0: cout << "0" << endl; continue; 
46             case 1: cout << "1" << endl; continue;
47             case 2: cout << "1" << endl; continue;
48         }
49         Matrix A, B;
50         A.x = 2; A.y = 2;
51         A.mat[1][1] = 1; A.mat[1][2] = 1;
52         A.mat[2][1] = 1; A.mat[2][2] = 0;
53         B.x = 2; B.y = 1;
54         B.mat[1][1] = 1; B.mat[2][1] = 1;
55 
56         mat_pow(A, N - 1);
57         mat_mul(A, B, B);
58         cout << B.mat[1][1] << endl;
59 
60     }
61     return 0;
62 }
复制代码

 

 

洛谷P1962 斐波那契数列

题目背景

大家都知道,斐波那契数列是满足如下性质的一个数列:

• f(1) = 1

• f(2) = 1

• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)

题目描述

请你求出 f(n) mod 1000000007 的值。

输入输出格式

输入格式:

 

·第 1 行:一个整数 n

 

 输出格式:

 

第 1 行: f(n) mod 1000000007 的值

 

输入输出样例

输入样例#1: 复制
5
输出样例#1: 复制
5
输入样例#2: 复制
10
输出样例#2: 复制
55

说明

对于 60% 的数据: n ≤ 92

对于 100% 的数据: n在long long(INT64)范围内。

首先看到数据范围,longlong以内,故我们考虑矩阵加速动态规划。

我们都知道斐波那契数列有这样的一个动态转移方程:f[i]=f[i-1]+f[i-2];

由此可以推出一个2×2的矩阵:1 1 1 0

然后就是套用矩阵快速幂的模板来加速。

以下是代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long lol;

lol n;
lol mod=1e9+7;
lol f[3][3],ans[3]={0,1,1};

void lu() {
lol t[3]={0};
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
t[i]=(t[i]+(ans[j]*f[j][i])%mod)%mod;
memcpy(ans,t,sizeof(ans));
}

void ge() {
lol t[3][3]={0};
for (lol i=1;i<=2;i++)
for (lol j=1;j<=2;j++)
for (lol k=1;k<=2;k++)
t[i][j]=(t[i][j]+(f[i][k]*f[k][j])%mod)%mod;
memcpy(f,t,sizeof(f));
}

int main() {
cin>>n;
if (n==1||n==2||!n) {
cout<<'1'<<endl;
exit(0);
}
n--;
f[1][1]=1;f[1][2]=1;
f[2][1]=1;f[2][2]=0;
while (n) {
if (n&1) lu();
ge();n>>=1;
}
cout<<ans[2]<<endl;
return 0;
}

 

转载于:https://www.cnblogs.com/Renyi-Fan/p/8142674.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三章

一.项目前期的主要工作 1.现状分析 ①.硬件分析 ②.软件分析 2.需求收集 3.粗略设计 ①.体系结构分析 ②.硬件&#xff08;网络&#xff09;设计 ③.应用系统设计 ④.安全设计 ⑤.配套设计 4.可行性分析 二.结构的项目前期实例 1.组织分析 3.需求收集 4.粗略设计 ①.系统体系结…

荣耀magic3会用鸿蒙,赵明:荣耀Magic3芯片领先行业,大家看到以后会换掉手机!...

荣耀CEO赵明亲自参加高通2021技术峰会&#xff0c;宣布与高通达成战略合作&#xff0c;未来全系产品采用高通平台。赵明同时透露未来的产品动向&#xff0c;不排除未来与华为继续合作&#xff0c;采用鸿蒙操作系统的可能。赵明表示&#xff0c;Android操作系统依旧是荣耀的首选…

三周第三次课 3.7 su命令 3.8 sudo命令 3.9 限制root远程登录

3.7 su命令1、su命令su命令是用来切换用户的&#xff1b;su命令需要使用- 进行切换&#xff0c;如果不使用- 也可以&#xff0c;但当前目录是在root下&#xff0c;没有彻底切换在root下 使用su命令创建文件&#xff0c;以指定用户的身份创建文件切换后显示-bash-4.2因为user5的…

html坐标绘制路径,canvas学习笔记之绘制简单路径

1 线段(直线路径)绘制线段一般步骤:moveTo(x,y) 移动画笔到指定的坐标点(x,y)lineTo(x,y) 使用直线连接当前端点和指定的坐标点(x,y)stroke() 根据当前的画线样式&#xff0c;绘制当前或已经存在的路径2 矩形路径绘制矩形路径一般步骤:rect(x, y, width, height) 矩形路径&…

增加表单的文字段的html的代码是,表单及表单新增元素(示例代码)

要想更好运用表单就要了解表单的的更多元素与属性&#xff0c;首先看看对表单基本了解。表单的基本了解 元素用于用户输入数据的收集元素是最重要的表单元素&#xff0c;有许多type其中是用于向表单处理程序提交表单的按钮。元素 元素定义待选择的下拉列表选项&#xff0c;元素…

给博客或站点加入百度统计

概述 记得刚接触百度统计的时候&#xff0c;苦于没有个人网站&#xff0c;不能加入统计代码查看访问量等数据。然后渐渐的忘了这件事。之前看别人博客中提及了百度统计&#xff0c;然后粗略的看了一下加入方法&#xff0c;觉得很惊喜&#xff0c;太简单了&#xff01; 加入方法…

项目规划管理

项目规划管理 - 1 项目规划是预测未来&#xff0c;确定要达到的目标&#xff0c;估计会碰到的问题&#xff0c;并提出实现目标、解决问题的有效方案、方针、措施和手段的过程。( 摘自百度百科) 大家应该都看过不少美国大片&#xff0c;是否记得很多片子里&#xff0c;特别是偷…

android9叫什么名字,白猜这么多名字!谷歌Android 9.0正式发布:命名Android Pie

日前&#xff0c;谷歌对外公布了Android P的beta版&#xff0c;并向索尼Xperia XZ2、小米Mi Mix 2S、诺基亚7 Plus、Oppo R15 Pro、Vivo X21、一加6和Essential PH-1开放测试。今天&#xff0c;谷歌终于宣布正式发布Android 9.0的正式版本。据外媒GSMArena报道&#xff0c;今天…

再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化

原文:再送一波干货&#xff0c;测试2000线程并发下同时查询1000万条数据库表及索引优化继上篇文章《绝对干货&#xff0c;教你4分钟插入1000万条数据到mysql数据库表&#xff0c;快快进来》发布后在博客园首页展示得到了挺多的阅读量&#xff0c;我这篇文章就是对上篇文章的千万…

wps html编辑表格,WPS 2017个人版演示word使用技巧(wps2017表格使用技巧)

wps2017是一款非常深受用户喜爱的办公软件。在2017这个新的版本中&#xff0c;依旧继承了它之前兼容免费、体积小、多种界面切换、云办公等众多优秀的功能特点&#xff0c;下面小编就来教大家wps2017的使用方式使用技巧&#xff1a;一、wps2017个人版word使用技巧技巧一&#x…

es Update API

2019独角兽企业重金招聘Python工程师标准>>> es Update API 博客分类&#xff1a; 搜索引擎&#xff0c;爬虫 The update API allows to update a document based on a script provided. The operation gets the document (collocated with the shard) from the ind…

Linux 线程占用CPU过高定位分析

今天朋友问我一个Linux程序CPU占用涨停了&#xff0c;该如何分析&#xff0c; CPU占用过高&#xff0c;模拟CPU占用过高的情况 先上一段代码&#xff1a; 1 #include <iostream>2 #include <thread>3 #include <vector>4 5 6 int main(int argc, char **argv…

计算机二级常备知识,2020年计算机二级Office考试必备题库资料!

考试资料在手&#xff0c;考试不用愁&#xff01;领报名界面显示计算机二级Office通过率仅21.07%&#xff0c;很多人认为是既费脑子又费时间的考试&#xff0c;可能是方法不对&#xff0c;导致花了很多时间还是考不过&#xff0c;刚刚收到3月考的二级证书啦&#xff0c;马上还有…

MR作业的提交监控、输入输出控制及特性使用

2019独角兽企业重金招聘Python工程师标准>>> MR作业的提交监控、输入输出控制及特性使用 博客分类&#xff1a; hadoop 提交作业并监控 JobClient是用户作业与JobTracker交互的主要接口&#xff0c;它提供了提交作业&#xff0c;跟踪作业进度、访问任务报告及logs、…

http协议与web本质

当你在浏览器地址栏敲入“http://www.csdn.net/”&#xff0c;然后猛按回车&#xff0c;呈现在你面前的&#xff0c;将是csdn的首页了&#xff08;这真是废话&#xff0c;你会认为这是理所当然的&#xff09;。作为一个开发者&#xff0c;尤其是web开发人员&#xff0c;我想你有…

Docker storage driver 选择

2019独角兽企业重金招聘Python工程师标准>>> Docker storage driver 选择 博客分类&#xff1a; docker 本文的目的是说明&#xff0c;如何在生产环境中选择Docker 的storage driver。以及对应Linux发行版本下Docker storage driver的配置方法。主要参考&#xff0c…

手机网站制作html5,【怎么样制作手机网站】如何使用dreamweavercs6建立手机网站?织梦手机WAP浏览模块如何制作手机网站?如何制作html5手机页面?...

【怎么样制作手机网站】如何使用dreamweavercs6建立手机网站?织梦手机WAP浏览模块如何制作手机网站?如何制作html5手机页面?下面就和小编一起来看看吧!如何使用dreamweavercs6建立手机网站?制作步骤如下:1。打开DreamweaverCS6软件&#xff0c;可以在DreamweaverCS6软件的开…

如果在docker中部署tomcat,并且部署java应用程序

2019独角兽企业重金招聘Python工程师标准>>> 如果在docker中部署tomcat,并且部署java应用程序 博客分类&#xff1a; docker 1、先说如何在docker中部署tomcat 第一步&#xff1a;root用户登录在系统根目录下创建文件夹tomcat7,命令如&#xff1a;mkdir tomcat7&…

Spring Boot结合thymeleaf

之前在Eclipse里写了个Spring Boot响应jsp的小demo&#xff0c;后来发现打成jar包导出之后找不到jsp文件了。经过在网上查阅信息与资料&#xff0c;发现Spring Boot对于jsp的支持其实是不好的&#xff0c;而且在一些书中和官方都明确表示没有办法支持在jar包中打入jsp文件。虽然…