快速幂与取模小结

        取模公式

       1)a≡a(mod d)
       2)对称性 a≡b(mod d)→b≡a(mod d)
       3)传递性 (a≡b(mod d),b≡c(mod d))→a≡c(mod d)
       如果a≡x(mod d),b≡m(mod d),则
      4)a+b≡x+m (mod d)
      5)a-b≡x-m (mod d)
      6)a*b≡x*m (mod d )
      7)a/b≡x/m (mod d)
      8) a≡b(mod d)则a-b整除d
      9)a≡b(mod d)则a^n≡b^n(mod d)
     10)如果ac≡bc(mod m),且c和m互质,则a≡b(mod m)
      模运算的运算规则:

      (a + b)  mod  p = (a  mod  p + b  mod  p)  mod  p            (1)
      (a - b)  mod  p = (a  mod  p - b  mod  p)  mod  p              (2) 
      (a * b)  mod  p = (a  mod  p * b  mod  p)  mod  p              (3)  //这个是没有除法的
      a^b  mod  p = ((a  mod  p)^b)  mod  p                              (4)
      结合率: ((a+b)  mod  p + c)  mod  p = (a + (b+c)  mod  p)  mod  p (5)
                     ((a*b)  mod  p * c) mod  p = (a * (b*c)  mod  p)  mod  p     (6)
      交换率: (a + b)  mod  p = (b+a)  mod  p                 (7)
                     (a * b)  mod  p = (b * a)  mod  p                 (8)
      分配率: ((a +b) mod  p * c)  mod  p = ((a * c)  mod  p + (b * c)  mod  p)  mod  p (9)
      重要定理:若a≡b ( mod  p),则对于任意的c,都有(a + c) ≡ (b + c) ( mod p);(10)
                        若a≡b ( mod  p),则对于任意的c,都有(a * c) ≡ (b * c) ( mod p);(11)
                        若a≡b ( mod  p),则对于任意的c,都有ac≡ bc ( mod p);     (13)

引申:一个数模p再模p.....==只模一次p

快速幂取模

循环写法

利用乘法模运算的公式

与乘方模运算    推其正确性

long long pow_mod(long long a,long long x,long long p)
{
	long long ans=1;               //p是取模的数
        long long base=a%p;
	while(x>0)
	{
           if(x&1==1)
           ans=(ans*base)%p;     //if里的条件也可以写成x&1
	   base=base*base%p;     
	   x=x>>1;
	}
	return ans;
}

 递归写法

long long pow_mod(long long a,long long x,long long p)
{
    if(x==0) 
    return 1;
    long long ans=pow_mod(a,x>>1,p);
    ans=ans*ans%p;
    if(x&1==1)
    ans=ans*a%p;
    return ans;
}

循环写法比递归写法快

指数用二进制表示就容易理解了

 

快速幂就是快速算出a^x。

快速幂的原理:二进制 2^10=2^2*2^8

long long pow_mod(long long a,long long x)
{
	long long ans=1;
	long long base=a;    //2^0=1,ans*=a;所以base每次从a开始,然后平方变化,所以base*=base;
	while(x!=0)
	{
		if(x&1==1)
               ans*=base;
               base*=base;
               x>>1;
	}
	return ans;

}

 

 矩阵快速幂

int n,mod;
int init[4],lastans[4],base[4][4],ans[4][4];                       //由n-x的x决定
void mul(int b[4][4],int a[4][4],int tans[4][4])
{
     int i,j,k;
     int t[4][4];
     for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            t[i][j]=0;
            for(k=0;k<4;k++)
            t[i][j]=(t[i][j]+b[i][k]*a[k][j])%mod;      //在答案出取余就好
        }
     for(i=0;i<4;i++)
     for(j=0;j<4;j++)
     tans[i][j]=t[i][j]%mod;
 }
void pow_mod()    //base[][],ans[][],n定成全局变量了
{
        int i,j;
        init[0]=2;init[1]=4;init[2]=6;init[3]=9;          //init是初始列矩阵,初始的f值
        memset(base,0,sizeof(base));
        memset(ans,0,sizeof(ans));
        memset(lastans,0,sizeof(lastans));
        base[0][1]=1;base[1][2]=1;base[2][3]=1;           // base是初始累乘矩阵
        base[3][0]=1;base[3][1]=1;base[3][3]=1;
        ans[0][0]=ans[1][1]=ans[2][2]=ans[3][3]=1;       //ans一开始是单位阵
        while(n>0)                                       //n是次方的次数。
        {
                if((n&1)==1)
                mul(base,ans,ans);
                mul(base,base,base);
                n=n>>1;
        }
        for(i=0;i<4;i++)
        {
           for(j=0;j<4;j++)
          {
            lastans[i]+=ans[i][j]*init[j];    //在答案出取余就好
          }
        }
        for(i=0;i<4;i++)
        lastans[i]%=mod;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值