ural1110 Power

编辑器加载中...

自己写了一个:
根据m^n mod y,m*m*...*m = y*x+r,再乘以m时相当于r乘以m即可
同理,令r = 1,r = (r*m)%y,这样相乘n次,我的模板(时间复杂度为O(n)),n太大时,可能超时:
int r = 1;
for(j=0;j<n;j++)
r = (r*i)%m;

求a^b%c(这就是著名的RSA公钥的加密方法)

  算法1:直接将b个a相乘,利用a*b%c=((a%c)*b)%c,每一步都进行这种处理,解决了a^b可能太大存不下的问题,这个算法的时间复杂度是O(n)。当b很大时运行时间会很长 。
  算法2:利用分治的思想,可以达到O(logn)。
可以把b按二进制展开为b=p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0)
其中p(i) (0<=i<=n)为0或1
这样a^b=a^(p(n)*2^n+p(n-1)*2^(n-1)+...+p(1)*2+p(0))
=a^(p(n)*2^n)*a^(p(n-1)*2^(n-1))*...*a^(p(1)*2)*a^p(0)
对于p(i)=0的情况,a^p(i)*2^(i-1)=a^0=1,不用处理
我们要考虑的仅仅是p(i)=1的情况
a^(2^i)=(a^(p(i)*2(i-1)))^2
利用这一点,我们可以递推地算出所有的a^(2^i)
当然由算法1的结论,我们加上取模运算a^(2^i)%c=((a^(2(i-1))%c)*a^(2(i-1)))%c
于是再把所有满足p(i)=1的a^(2^i)%c按照算法1乘起来再%c就是结果

示例:
3^6%7=3^(2^2)*3^(2^1)%7
=((3^(2^1))^2%7)*(3^1*3^1%7)
=(((3^1*3^1%7)%7)^2%7*2%7)%7
=(4*2)%7
=8%7
=1

快速幂算法(时间复杂度为O(logn)),如下:

(输入a,k,m,求a^k%m)
long f(long a,long k,long m)
{
long b=1;
while(k>=1)
{
if(k%2==1)
b=a*b%m;
a=a*a%m;
k=k/2;
}
return b;
}


#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
int i,j,n,m,y;

while(scanf("%d%d%d",&n,&m,&y)!=EOF)
{
int flag = 0;
for(i=0;i<m;i++)
{
int r = 1;
for(j=0;j<n;j++)
r = (r*i)%m;
if(r==y)
{
if(flag) //如果已打印的话
cout<<" ";
flag = 1;
printf("%d",i);
}
}
if(flag)
cout<<endl;
else //如果没搜到
cout<<-1<<endl;
}
return 0;
}

 

posted @ 2012-02-29 22:34  yejinru  阅读(192)  评论(0编辑  收藏  举报