一些数学笔记

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.同余的性质

aa(mod p)
ab(mod p)ba(mod p)
ab(mod p),b=c(mod p) 则 a=c(mod p)
ab(mod p),c=d(mod p) 则 a +/-/* c = b +/-/* d (mod p)
ab(mod p) 则 ak=bk(mod pk)
d|a,d|b,d|p a/db/d(mod p/d)d|p,ab(mod p)ab(mod d)
ab(mod p) 则gcd(a,m)==gcd(b,m).
若d可整除m及a,b中的一个,则d必定可以整除a,b中的另一个

posted @   Diamondan  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示