一些数学笔记
1.二进制 汉明权重(即二进制下1的个数)
算法极为easy:
// 求 x 的汉明权重1
int popcount(int x) { //(lowbit版)
int cnt = 0;
while (x) {
cnt++;
x-=x&-x;(lowbit操作)
}
return cnt;
}
// 求 x 的汉明权重2
int popcount(int x) { //(朴素版)
int cnt = 0;
while (x) {
cnt+=x&1;
x>>=1;
}
return cnt;
}
//当然还有强大的bitset<>
2.平衡三进制(不知道有啥用...)
就是用-1,0,1表示三进制,其中-1常用Z表示
具体变法:(找规律)就是一个数可以由一个三进制数减去另一个三进制得到
-1 Z
-2 Z1
-3 Z0
-4 ZZ
-5 Z11
0 0
1 1
2 1Z
3 10
4 11
5 1ZZ
6 1Z0
7 1Z1
8 10Z
9 100
3.快速幂
(应该算是用了二进制拆分的优化吧)
板子:
long long binpow(long long a, long long b) {
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
//模意义下快速幂 正常取模即可
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
根据费马小定理,如果m是一个质数,我们可以计算x^(n mod (m-1))来加速算法过程
4.矩阵乘法
最快的循环写法 i,k,j(i,j,k快5倍)
for(int i=0;i<n;++i)
for(int k=0;k<n;++k)
s=A[i][k];
for(int j=0;j<n;++j)
C[i][j]+=s*B[k][j];
5.素数
1)fermat素性测试
利用费马小定理,a^(n-1)=1(mod n) ,随机选取k个a,检验是否为素数,k一般>=8
但并不是所有数都满足,比如那些费马伪素数,虽然数量无限,但是占仍是小部分,仍有可行性
bool FM(int n) {
if(n<3) return n==2;
for(int i=1; i<=test_time; ++i) {
int a=rand()%(n-2)+2;
if(quickPow(a,n-1,n)!=1) return 0;
}
return 1;
}
2)Miller_Rabin素性测试
结合费马小定理与二次探测定理
二次探测定理:若p为奇素数,则x^2=1(mod p)的解为x=1(mod p)或者x=p-1(mod p)
将a^(n-1)=1(mod n)中指数n-1分解为u*2t,随机选取a,求出au(mod n)执行之多k次平方
发现非平凡平方根直接pass掉,否则就通过了该测试
// C++ Version
bool millerRabin(int n){
if(n<3||n%2==0) return n==2;
int a=n-1,b=0;
while(a%2==0) a/=2,++b;
for(int i=1, j; i<=test_time; ++i){
int x=rand()%(n-2)+2,v=quickPow(x,a,n);
if(v==1) continue;
for (j=0; j<b; ++j){
if(v==n-1) break;
v=(long long)v*v%n;
}
if(j>=b) return 0;
}
return 1;
}
6.反素数
对于一个正整数n,所有小于n的数的约数个数都小于n的约数个数的数
类比一下素数,素数约数最少,而反素数约数最多
不妨可以这样理解:反素数就是因子数最早(即越小)达到一个数k的数
所以不难发现反素数具有如下性质:质因子都相邻,从2开始连续
7.欧拉函数phi
表示小于n的与n互质的数的个数
欧拉定理:若gcd(a,m)=1,则a^phi(m)=1(mod m)
扩展欧拉定理:...
8.逆元
ax=1(mod b),那么x称为a mod b的逆元,记作a^-1
用法:
for example: (a/b)%p!=(a%p / b%p)%p
(100/50)%20 =2 != (100%20)/(50%20)%20 = 0
逆元的作用
一句话就是,将除法改为乘法;
例如 求 (A / B) %p ;
在B的值非常大的情况下,B作为除数,极有可能会爆精度;
除数不能太大;
所以我们可以把他转化为乘法来解决;
(a/b)mod m = (a/b)*1mod m = (a/b)bc mod
m=ac(mod m);
即a/b的模等于a * (b的逆元)的模;
所以按照这个推论求这个式子的步骤就明了了;
求出B的逆元 (扩展欧几里得,费马小引理+快速幂)都可以求出;
引用公式推论套用即可;
9.费马小定理
若p为素数,gcd(a,p)==1,则a^(p-1)=1(mod p) OR a^p=a(mod p)
用于求解逆元: a^(b-1)=1(mod b) -> ax=a^(b-1) (mod b)
ll ksm(ll a,ll b) {
ll res=1;
a%=mod;
while(b) {
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res%mod;
}
ll get_inv(ll m,ll n) {//用于求m/n % mod的值
return (m*ksm(n,mod-2))%mod;
}
10.同余的性质
若
若d可整除m及a,b中的一个,则d必定可以整除a,b中的另一个
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?