使用二进制的思想降低时间复杂度
2017-02-25 08:58
176 查看
如何使用二进制解决问题
正如通过高精度模拟可以获得500位以上的加减乘除运算外,当对于过大范围的运算我们可以将问题转化为二进制从而简便运算,使运算的一部分复杂度由n转化为log(n)- 首先是我们熟知的快速排序,即通过不断得将要排序的数组进行中等划分,进而递归成更小的数组,最后获得一个排序完的数组,qsort()其实就可以实现这个过程,不过手打的话可以更清楚一些。
code
void quiksort(int a[],int low,int high) { int i = low; int j = high; int temp = a[i]; if( low < high) { while(i < j) { while((a[j] >= temp) && (i < j)) { j--; } a[i] = a[j]; while((a[i] <= temp) && (i < j)) { i++; } a[j]= a[i]; } a[i] = temp; quiksort(a,low,i-1); //不断的将数组递归成更小的数组 quiksort(a,j+1,high); } else { return; } }
取余运算
输入b,p,k的值,编程计算b^p mod k的值。其中的b,p,k*k为长整型数(2^31范围内)。(参见codevs 1497)
这里如果每一步相乘然后取余的话那么会有一组数据过不了,至于为什么只有一组数据,我也不想说什么,好像codevs的数据一直很友好。那么对于2^31那么至少要运算10^9,而计算机每秒约运算10^6次,明显要算个2,3分钟。所以此时可以考虑使用二进制将运算的复杂度降低为log(n)。
题解
首先对一开始的p转化为二进制,然后对每次取余后的值平方,从而获得2^k次的运算结果,同时用一个数组保存这个结果,最后将这个结果与原先的p的二进制进行匹配,这样至多就只需要进行31次运算了.
code
#include<iostream> #include<stdio.h> using namespace std; int num[100]={0}; int num1[100]={0}; int main(void) { long long b,p,k,sum=1; cin>>b>>p>>k; long long m=b%k,count=0,ans=p; while(p!=0) { num[count]=p%2; p/=2; count++; } for(int i=1;i<count;i++) { m*=m; m%=k; num1[i]=m; } for(int i=count-1;i>=1;i--) { if(num[i]) { sum*=num1[i]; sum%=k; } } if(ans%2) sum*=b; cout<<b<<'^'<<ans<<" mod "<<k<<'='<<sum%k<<endl; }
相关文章推荐
- 使用动态编程方法,在降低时间复杂度的情况下获得背包问题的最优解
- [算法] 使用“复杂”的数据结构降低时间复杂度
- 关于使用二分思想算法的时间复杂度的计算
- 某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间
- 空间换时间,把递归的时间复杂度降低到O(2n)
- 素数(降低时间复杂度)
- offer题11 数值的整数次方&判断浮点型是否相等&降低求n次方的时间复杂度&3种错误处理方式
- 363. Max Sum of Rectangle No Larger Than K (如何降低时间复杂度)
- 算法导论12.2-8 从任意结点使用后继函数k次的时间复杂度为O(k+h)
- 11. 常见的有哪几种排序算法,试比较其时间复杂度,以及是否稳定,及各自使用的情形
- 空间换时间,把递归的时间复杂度降低到O(2n)
- 算法13 使用o(1)的时间复杂度去删除一个节点
- 题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。
- 使用栈在O(1)的时间复杂度求最大值
- hdu 4467 Graph ( 神奇的思想 降低复杂度 )
- !HDU 1506 Largest Rectangle in a Histogram-dp|单调队列-(dp降低时间复杂度)
- 使用scrapy爬取stl容器的时间复杂度
- PHP 中巧用数组降低程序的时间复杂度
- 算法导论12.2-7 证明使用后继函数进行中序遍历的时间复杂度为Θ(n)
- 使用O(n)的时间复杂度合并两个数组