蒟蒻复习之—–数学

14 篇文章 0 订阅

//以下是我的一些模板的整理
//只有板子,没有原理

#素数#
##1.素数判定##

O(根号n)

bool prime(int x) {
	if(x == 0 || x == 1) return false;
	for(int i = 2; i * i <= x; i++) {
		if(x % i == 0) return false;
	}
	return true;
}

##2.筛素数##
//其实noip上一般不会卡筛素数的,但还是要会O(n)的欧拉筛

int init_prime() {
	memset(check,0,sizeof(check));
	memset(prime,0,sizeof(prime));
	cnt = 0;
	for(int i = 2; i <= inf; i++) {
		if(!check[i]) prime[++cnt] = i;
		for(int j = 1; j <= cnt && i * prime[j] <= inf; j++) {
			check[i * prime[j]] = 1;
			if(i % prime[j] == 0) break;
		}
	}
}

##3.区间筛素数##
(poj2689)
筛[a,b)中的素数
因为b以内合数的最小质因数一定不超过sqrt(b),先分别做好[2,sqrt(b))的表和[a,b)的表,然后从[2,sqrt(b))的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了。

void qj_prime(int a, int b) {
	for(int i = 0; i * i < b; i++) sq[i] = 1;//[1,sqrt(b))中的
	for(int i = 0; i < b-a; i++) check[i] = 1;//下标位移
	if(1-a >= 0) check[1-a] = 0;
	for(int i = 2; i * i < b; i++) {
		if(sq[i]) {
			for(int j = 2 * i; j * j < b; j += i) sq[j] = 0;
			 //(a+i-1)/i得到最接近a的i的倍数,最低是i的2倍,然后筛选
			for(int j = max(2,(a + i - 1) / i) * i; j < b; j += i) check[j - a] = 0;
		}
	}
	for(int i = 0; i < b-a; i++) {
		if(check[i]) prime[++cnt] = i + a;
	}
}

##4.分解质因数##
基于唯一分解定理
n = P1^a1 * P2^a2 * …………* Pn^an(P1 < P2 < ……Pn),Pi为质数;

朴素法(可以先求出素数来优化一下)

void solve(int x) {
	for(int i = 2; i * i <= x&& x > 1; i++) {
		if(x % i == 0) {
			zhi[++cnt] = i;
			while(x % i == 0) {
				check[cnt]++;
				x /= i;
			}
		}
	}
	if(x > 1) zhi[++cnt] = x, check[cnt]++;
}

##5.欧拉函数##
为小于n且与n互质的数的个数(包含1)
对于一个正整数N的素数幂分解 N=P1q1*P2q2*…*Pn^qn.
φ(N)=N * (1-1/P1) * (1-1/P2) * … * (1-1/Pn).

int fai[maxn];
void ol(int N){
	memset(check,0,sizeof(check));
	tot = 0; fai[1] = 1;
	for(int i = 2; i <= N; ++i){
		if(!check[i]){
			prime[++tot] = i;
			fai[i] = i - 1;
		}
		for(int j = 1; j <= tot && i * prime[j] <= N; ++j){
			check[i*prime[j]] = 1;
			if(i % prime[j] == 0) {
				fai[i*prime[j]] = fai[i] * prime[j];
				break;
			} else {
				fai[i*prime[j]] = fai[i] * (prime[j] - 1);
			}
		}
	}
}

##规律##

1.因数个数为奇数的数为完全平方数
2. 因数个数 :(a1 +1)*(a2+1)*.....*(an+1)//a i 为唯一分解定理得到的指数
3.n!质因数分解这里写图片描述

#快速幂#

// a ^ b % mod
int ksm(int a, int b, int mod) {
	int ans = 1;
	a %= mod
	while(b) {
		if(b & 1) ans = (ans * a) % mod;
		b >>= 1;
		a = (a * a) % mod
	}
	return ans;
}

#排列组合#
这里写图片描述

##组合##

void init(){
	f[0][0]=1;
	for(int i = 1; i <= inf; ++i){
		f[i][0]=1;
		for(int j = 1;j <= i; ++j){
			f[i][j] = f[i-1][j] + f[i-1][j-1];
		}
	}
}

next_permutation(a +1,a+1+n); 下一个全排列
#同余#
这里写图片描述
#欧几里得算法#
##1.最大公因数##

int gcd(int a,int b) {
	if(!b) return a;
	else return gcd(b, a % b);
}

##2.最小公倍数##
gcd(a,b) * lcm(a,b) = a * b;
lcm(a,b) = a * b / gcd(a,b);

int lcm(int a,int b) {
	return a * b / gcd(a,b);
}

这里写图片描述

#扩展欧几里得算法#

void exgcd(int a, int b, int &d, int &x, int &y) {
	if(!b) {d = a, x = 1, y = 0, return;}
	exgcd(b, a % b, d , y, x); 
	y -= x * (a / b);
}

#逆元#
##1.扩欧#
这里写图片描述

int inv(int a, int n) {
	int d,x,y;
	exgcd(a,n,d,x,y);
	return (x % n + n) % n;
}

##2.费马小定理##
a^(p-1) ≡1 (mod p)

int inv(int a, int n) {
	return ksm(a,n-2,n)
}

#递推规律及乱七八糟#
##1.Catalan数##
这里写图片描述

h(n)=(4n-2)/(n+1)*h(n-1)(n>1) h(0)=1
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + … + h(n-1)h(0) (n>=2)
h(n)=C(2n,n)/(n+1)

##2.错排公式##

十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
f[1] = 0, f[2] = 1
f[i]=(i-1)*(f[n-1]+f[n-2])

##3.斐波那契数列##

f[1] = 1, f[2] = 1;
f[i] = f[i - 1] + f[i - 2]

##5.除数函数##
设 d(n)为 n 的所有因数的个数,由乘法原理可知,

d(n)=(a1 +1)(a2 +1)…(ak +1)。

##4.秦九韶算法##

这里写图片描述

int qing(int x){
	int ans=a[n];
	for(int i=n-1;i>=1;i--)
		ans=ans*x+a[i];
	return ans;
}

##5. n化为k进制##

while(n) a[++cnt] = n % k, n /= k;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值