您的位置:首页 > 其它

使用二进制的思想降低时间复杂度

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二进制
相关文章推荐