zoukankan      html  css  js  c++  java
  • 欧拉函数代码实现及扩展--快速矩阵幂

    参见博客:http://www.cnblogs.com/linyujun/p/5194170.html

          https://www.cnblogs.com/wudi-accept/p/5667714.html

    欧拉函数的定义:

    Φ(n)=小于n的数中与n互质的数的数目。

    在写代码之前,我们先看一下,欧拉函数的一个性质

    对于任意一个正整数,Φ( n ) = n * (1 - 1 / a1) * (1 - 1 / a2) * … * (1 - 1/an)。其中,a1 a2 … an 为所有 n 的质因子

    欧拉函数实现代码:

     1 int func(int n)
     2 {
     3     int temp=n;
     4     for(int i=2;i*i<=n;i++)
     5     {
     6         if(n%i==0)//是否是质因数
     7         {
     8             temp=temp*(i-1)/i;
     9             while(n%i==0)
    10             {
    11                 n/=i;
    12             }
    13         }
    14     }
    15     if(n>1)temp=temp*(n-1)/n;//如果n!=1,n也是其中一个质因数
    16     return temp;
    17 }

    欧拉函数扩展,求大数快速矩阵幂


    题目描述:

    给a,b,c三个数字,求a的b次幂对c取余。

    数据范围:多组样例循环输入,每一组输入a,b,c (1<=a,c<=10^9,1<=b<=10^1000000)。

    输入:

    2 2 2
    139123 123124121241452124412124 123121

    输出:

    0

    8984

     


     

    首先知道一个欧拉函数的一个性质:

    ab%p==ab%Φ(p)+Φ(p)%p  (证明不会,还请大佬留言)

    快速矩阵幂算法  代码:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 using namespace std;
     5 typedef long long ll;
     6 char b[1000100];
     7 ll func(ll n)//欧拉函数
     8 {
     9     ll temp=n;
    10     for(int i=2;i*i<=n;i++)
    11     {
    12         if(n%i==0)//是否是质因数
    13         {
    14             temp=temp*(i-1)/i;
    15             while(n%i==0)
    16             {
    17                 n/=i;
    18             }
    19         }
    20     }
    21     if(n>1)temp=temp*(n-1)/n;//如果n!=1,n也是其中一个质因数
    22     return temp;
    23 }
    24 
    25 ll POW(ll a,ll b,ll p)//快速矩阵幂
    26 {
    27     ll ans=1;
    28     while(b!=0)
    29     {
    30         if(b%2!=0)
    31         {
    32             ans=ans*a%p;
    33         }
    34         b=b>>1;
    35         a=a*a%p;
    36     }
    37     return ans;
    38 }
    39 
    40 int main()
    41 {
    42     ll a,p;
    43     while(cin>>a)
    44     {
    45         scanf("%s%lld",b,&p);
    46         ll len = strlen(b);
    47         ll oula = func(p);
    48         int temp=0;
    49         for(ll i=0; i<len; i++){ //降幂
    50             temp = (temp*10+b[i]-'0')%oula;//模运算的性质
    51         }
    52         cout<<POW(a,temp+func(p),p)<<endl;
    53     }
    54 
    55 }

     【如有侵权,请告知,立即删除】

    ab%p=ab%(p1)%p

    ab%p=ab%(p1)%p

    ab%p=ab%(p1)%p

  • 相关阅读:
    JDK源码分析 – HashMap
    牛哄哄的celery
    redis数据库基础篇
    RPC的入门应用
    Python的常用模块
    消息队列之真知灼见
    面向对象编程(2)
    python3的C3算法
    面向对象编程(1)
    CRM项目之stark组件(2)
  • 原文地址:https://www.cnblogs.com/xia520/p/8869395.html
Copyright © 2011-2022 走看看