数学基础:模运算、数位拆解、进制转换与快速求幂
首先对%的特点做一个整理。
1)a%b,a和b都必须为整形变量而不能为浮点数;b不能为0,否则RE
2)a%b=r,r的符号与a一致而与b无关,与数学意义上标准的模运算有区别。具体处理过程是|a|%|b|=|r|,再给r的符号进行处理。为了排除r为负的影响,不妨再加一步:r=(r+b)%b
3)(a+b)%c=(a%c+b%c)%c;(a-b)%c=(a%c-b%c)%c;(a*b)%c=(a%c*b%c)%c;(a^b)%c=(a%c)^b)%c;注意除法没有类似规律,(a/b)%c=(a%c*b^(-1)%c)%c;
更多细节见https://baike.baidu.com/item/取模运算/10739384?fr=aladdin
接下来是数位拆解,顾名思义,将一个数的各位拆解开来。
while(a!=0){
int b=a%i;
a/=i;
}
但是要小心a==0的情况,a=0直接跳过了分解步骤。而且目前得到的结果是倒序。除此之外还有一种方法是把输入的数字看作字符串,直接对字符依次进行处理
进制转换是围绕十进制来进行的,先转化成十进制再处理。由高位转低位,选择不同的进制进行数位拆解;低位转高位直接各位权*各位值加起来就行
二分求幂/快速求幂,处理a^b。其思想是将b变为2进制,根据每位是否为1进行累乘,从而快速求解。例洛谷P1226
#include<bits/stdc++.h>
using namespace std;
long long b,p,k;
int main()
{
scanf("%lld%lld%lld",&b,&p,&k);
long long t1=b,t2=p,t3=k;
long long ans=1;
while(p!=0){ //坑点,如果p==0会不进行模运算,需要初始化
if(p%2==1){
ans*=b;
ans%=k;
}
p/=2;
b*=b;
b%=k;
}
printf("%lld^%lld mod %lld=%lld\n",t1,t2,t3,ans%k);
return 0;
}
同样类似思想的,还有快速乘。本质都是为了避免爆出数据范围。


浙公网安备 33010602011771号