数学知识积累
2014-03-04 21:34
204 查看
快速求幂算法
参见了别人的博客http://blog.sina.com.cn/s/blog_3f2fa9610100soxb.html,了解到了快速求幂的一种方法,比简单的循环相乘要大大减少乘法次数,自己学习后写的c++代码如下bigint power(bigint x, int n) { bigint ret; ret.set(1); while (n!=0) { if (n&1==1) ret=ret*x; x=x*x; n>>=1; } return ret; }这里用到了位运算,同时提高了运算效率。bigint数据类型是我自己定义的,可忽略。
接着上一步继续深入,当我们需要对一个很大的乘幂结果取模时,由于a*b%m=(a%m)*(b%m)的原理,可以将取模过程融入到快速求幂过程中,将代码稍加改进即可:
bigint power(bigint x, int n, int k) { bigint ret; ret.set(1); while (n!=0) { if (n&1==1) ret=(ret*x)%k; x=(x*x)%k; n>>=1; } return ret; }
同样这也是从大神的博客学来的http://blog.sina.com.cn/s/blog_8619a25801010wcy.html。看来要想学好计算机,一定要好好学数学,这是读研的重要任务之一。
矩阵乘法在数列递归中的运用
今天做清华的一道数列递归题,如果用递归算法实现起来十分容易,可是显然这道题不是考递归算法,含有的大数据一定会超时。我想了很久也找不到解决方法,上网看才知道有一种我从来没见过的算法,即矩阵乘法在数列递归中的运用。一个典型的例子就是斐波那契数列的非递归算法,具体参考这里 http://blog.sina.com.cn/s/blog_6ea2c6a20100x359.html 。运用矩阵的二分乘,可以大大降低复杂度,达到O(logn),二分乘就是上面讲到的快速求幂法。二阶方阵的乘法代码如下:
matrix mul(matrix &x, matrix &y) { matrix ret; ret.a[0][0]=(x.a[0][0]*y.a[0][0]+x.a[0][1]*y.a[1][0])%MOD; ret.a[0][1]=(x.a[0][0]*y.a[0][1]+x.a[0][1]*y.a[1][1])%MOD; ret.a[1][0]=(x.a[1][0]*y.a[1][1]+x.a[0][0]*y.a[1][0])%MOD; ret.a[1][1]=(x.a[1][0]*y.a[0][1]+x.a[1][1]*y.a[1][1])%MOD; return ret; }
素数筛法
之前已经写过相关代码,可是遇到同样的题还是错了。主要原因是当时没有理解为什么要用素数筛。现在学习到,判断质数的暴力法时间复杂度为O(n),而素数筛可以将其降为O(sqrt(n)),原因是当搜索到sqrt(n)后,还没找到能整除n的整数,那么n为质数,假设存在x>sqrt(n),能整除n,那么一定有y=n/x<sqrt(n),能整除n,那么在搜索到sqrt(n)之前就可以判断n不是质数了。同样,在找整数n的质因数时,从2开始依次用质数整除,当除到sqrt(n)商还不为0时,那么这个商本身就是一个质数,在原来的质因数数量上+1即可。素数筛法的初始化代码如下:void init() { for (int i=0;i<MAX;++i) mark[i]=true; mark[0]=mark[1]=false; size=0; for (int i=2;i<MAX;++i) { if (mark[i]==true) { prime[size++]=i; for (int j=2;i*j<MAX;++j) mark[i*j]=false; } } }
位运算
与运算&可用于二进制取位操作,例如想取x的末尾,直接x&1,取倒数第二位,则x&2,以此类推,要去一个二进制数的倒数第n为,则将该数和2^(n-1)相与,若为0则该位为0,否则该位为1。移位操作可以快速得到2^n的数,如要得到2^5,只需要将1左移5位,即1<<5。
或操作可以将目标二进制位强制转化为1。
在使用位运算的时候要注意运算优先级的问题,由于优先级较低,最好加括号,避免不必要的错误~
相关文章推荐
- 机器学习(2.4)数据知识积累——高等数学
- 机器学习(2)数学知识积累
- 数学基础知识积累——傅里叶分析
- 碰到的有用的数学知识积累
- 数学基础知识积累——范数
- Linux知识积累(长更)
- 【知识积累】使用Navicat连接Oracle数据库遇到的问题
- 数学-知识记录
- 一个有意思的数学知识网站
- ORACLE-日期的使用(知识积累)
- ubuntu 知识 积累
- SVN库的目录结构(知识积累)
- python琐碎的知识积累,闭包
- 机器学习中的基本数学知识
- 【cocos2d-x 小知识积累和备忘】
- 机器学习数学基础知识备忘
- Linux知识积累(4) Linux下chkconfig命令详解
- Java正则表达式――知识积累
- java线程的简单知识积累
- 入门机器学习需要预备哪些数学知识?