一、模重复平方计算法
1.内容
2.思路
1)计算将x写出二进制的形式,2的最高次数
2).将x写出二进制,arr[i]保存ni,取值0/1
3)输出最小的非负解
3.代码
#include<iostream>
using namespace std;
int main()
{
int k=0,x=0,m=0;//底数 指数 模
cin>>k>>x>>m;
int n=0,i=1;
while(i<x) //计算x的最高次数
{
if(x/i<2) break;
else
{
i*=2;
n++;
}
}
int arr[n+1],a[n+1],b[n+1]; //ni(0/1) ai bi
int temp=x;
for(int j=n;j>=0;j--)
{
if(temp/i>=1)
{
arr[j]=1;
temp=temp%i;
}
else arr[j]=0;
i/=2;
}
b[0]=k%m;
if(arr[0]==1) a[0]=b[0];
else a[0]=1;
for(int j=1;j<=n;j++)
{
b[j]=(b[j-1]*b[j-1])%m;
if(arr[j]==1) a[j]=(a[j-1]*b[j])%m;
else a[j]=a[j-1];
}
cout<<a[n];
}
二、中国剩余定理
1.内容
2.思路
1)先输入n,m[n],b[n],并将所有的mi相乘结果保存至M中
2)Mi=M/mi,求出Mi的逆元j,x+=Mi*j*b[i]
3)输出最小的非负解
3.代码
#include<iostream>
using namespace std;
int main()
{
int n=0;
cin>>n;
int m[n],b[n];
int M=1; //将m[n]累乘
for(int i=0;i<n;i++)
{
cin>>m[i];
M*=m[i];
}
for(int i=0;i<n;i++)
{
cin>>b[i];
}
int x=0;
int Mi=0;
for(int i=0;i<n;i++)
{
Mi=M/m[i];
for(int j=1;j<m[i];j++) //得到Mi的逆元j
{
if(Mi*j%m[i]==1)
{
x+=Mi*j*b[i]; //x等于Mi*j*b[i]的累加
break;
}
}
}
cout<<x%M;
}