Chinaunix首页 | 论坛 | 博客
  • 博客访问: 73165
  • 博文数量: 30
  • 博客积分: 2133
  • 博客等级: 大尉
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-12 13:33
个人简介

aaa

文章分类
文章存档

2010年(30)

我的朋友
最近访客

分类:

2010-04-12 14:53:01

欧拉定理: 设 m 是大于 1 的整数,如果  a  是满足 (a,m)== 1 的整数,则 a f(m)=1 ( mod m )

证明: 取 r1, r2, r3, ... , rf(m) 为比 m 小且与 m 互素的数, 有 ( ri, m )== 1, 因为 (a,m)== 1, 故有 (a*ri, m)= 1。

可以证明 a*ri != a*rj ( mod m ) (i!= j ),因为假设上式成立,则有 ri== rj ( mod m ) (i!= j ),而这个式子是不成立的。由此我们可以得出: (a* r1)( a* r2)...(a*rf(m) )== r1r2...rf(m)  (mod m )

故 r1* r2* ... * rf(m)* (af(m)-1)== 0 ( mod m )

又  r1* r2* ... * rf(m) == 1 (mod m)   所以 (af(m)-1)== 0 ( mod m )。

 

费马小定理:设 p 是一个素数,则对任意整数 a, 我们有 ap== a ( mod p )

证明: 我们分两种情况考虑

1) 若 p| a,则同时有 p| ap,显然 ap== a ( mod p )。

2) 若 (p, a)== 1,所以 (p, ap-1)= 1,则由欧拉定理有 ap-1== 1 ( mod p ),两端同乘 a,则得到:

     ap== a ( mod p )。

 

推论: 设 a, p, n 为正整数,则有 ap== ap % f(n)+ f(n)  ( mod n )。

 

Hnu 11694 Fibnacci Numbers

代码:

#include <iostream>
using namespace std;
__int64 a,x,n;
__int64 mod;

int Eular(int n){
    int ret=1;
    for(int i=2;i*i<=n;++i)
    if(n%i==0){
        n/=i;ret*=i-1;
        while(n%i==0){
            n/=i;ret*=i;}
    }
    if(n>1)ret*=n-1;
    return ret;
}

void inline mult(__int64 x[4][4], __int64 y[4][4]){
    __int64 z[4][4];
    for(int i=0;i<4;++i)
    for(int j=0;j<4;++j){
        z[i][j]=0;
        for(int k=0;k<4;++k)
        z[i][j]=(z[i][j]+x[i][k]*y[k][j])%mod;
    }
    for(int i=0;i<4;++i)
    for(int j=0;j<4;++j)
    y[i][j]=z[i][j];
}

int main(){
    while(cin>>a>>x>>n){
        if(a==0&&x==0&&n==0)return 0;
        __int64 d[4][4], ans[4][4]={0};
        d[0][0]=1;d[0][1]=1;d[0][2]=1;d[0][3]=2;
        d[1][0]=0;d[1][1]=1;d[1][2]=1;d[1][3]=2;
        d[2][0]=0;d[2][1]=1;d[2][2]=0;d[2][3]=0;
        d[3][0]=0;d[3][1]=1;d[3][2]=0;d[3][3]=1;
        
        __int64 sn=0;
        mod=Eular(n);
        if(x==1)sn=1;
        else if( x==2)sn=5;
        else{
            for(int i=0;i<4;++i) ans[i][i]=1;x-=2;
            while(x>0){
                if(x&1)mult(d,ans);
                mult(d,d);x/=2;
            }
            sn= (ans[0][0]*5%mod+ans[0][1]*4%mod+ans[0][2]+ans[0][3]*2)%mod;
        }
        sn+=mod;
        __int64 as=1,t=a;
        while(sn){
            if(sn&1)as=as*t%n;
            t=t*t%n;sn>>=1;}
        cout<<as<<endl;
    }
    return 0;
}


阅读(668) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~