基础数学知识学习笔记

一、分解质因数

1. 试除法

模板:复杂度 O(sqrt(n))

void solve(int n){
     
	for(int i=2;i<=n/i;i++){
     
		if(n%i==0){
     
			int sum=0;
			while(n%i==0){
     
				n/=i;
				sum++;
			}
			cout<<i<<" "<<sum<<endl;
		}
	}
	if(n>1) cout<<n<<" "<<1<<endl;
}

二、筛质数

1.普通筛

模板:复杂度 O(n*logn)

int n,prime[N],p[N],cnt;
void solve(){
     
	for(int i=2;i<=n;i++){
     
		if(prime[i]==0){
     
			p[++cnt]=i;
			for(int j=2;j*i<=n;j++) prime[j*i]=1;
		}
	}
}

2.线性筛

模板:复杂度 O(n)

int n,prime[N],p[N],cnt;
void solve(){
     
	for(int i=2;i<=n;i++){
     
		if(prime[i]==0) p[++cnt]=i;
		for(int j=1;j<=cnt&&i*p[j]<=n;j++){
     
			prime[i*p[j]]=1;
			if(i%p[j]==0) break;
		}
	}
}

三、快速幂

模板:

LL qp(LL a,LL b){
     //是求a的b次方
    LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
    while(b>0){
     
        if(b&1ll) ans=(ans*base)%mod;
        base=(base*base)%mod;
        b>>=1ll;
    }
    return ans;
}

四、逆元

同余不满足除法,即 (a/b) % p != (a % p) / (b % p) ;

这里主要说明分数取模的方法,对于 (a/b) % p,可以先求出 b 在 % p 下的逆元,然后乘上a,再mod p,就是分数取模的值了;

逆元的求解方法:

1.费马小定理

当 p 为素数,且 a 为正整数,并且 a,p 互质,则逆元就等于 a p − 2 a^{p-2} ap2%p;
所以只要运用快速幂就可以;

模板题:洛谷·P2613 【模板】有理数取余

模板:

LL qp(LL a,LL b){
     //是求a的b次方
    LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
    while(b>0){
     
        if(b&1ll) ans=(ans*base)%mod;
        base=(base*base)%mod;
        b>>=1ll;
    }
    return ans;
}
int main(){
     
	string s1,s2;cin>>s1>>s2;
	LL a=0,b=0;
	int len1=s1.length(),len2=s2.length();
	for(int i=0;i<len1;i++){
     
		a*=10;a+=s1[i]-'0';
		a%=mod;
	}	
	for(int i=0;i<len2;i++){
     
		b*=10;b+=s2[i]-'0';
		b%=mod;
	}	
	if(b==0) cout<<"Angry!"<<endl;
	else{
     
		LL ans=a*qp(b,mod-2ll);
		cout<<(ans%mod+mod)%mod<<endl;
	}
	return 0;
}

五、拓展欧几里得

扩展欧几里得是用来求 ax + by = gcd(a,b) 中的未知数的,那么如果等式不等于 gcd(a,b) 怎么办呢?
比如:ax + by = z,记住一点就是等式有解必须保证 z%gcd(a,b)==0,所以可以先利用扩展求出 ax + by = gcd(a,b) 的解,然后乘上 z/gcd(a,b) 就可以;

模板题:洛谷·P1082 同余方程

模板:

LL x,y;//方程的解
void exgcd(LL a,LL b){
     
	if(b==0){
     
		x=1,y=0;
		return;
	}
	exgcd(b,a%b);
	LL tx=x;
	x=y;
	y=tx-a/b*y;
} 
int main(){
     
	LL a,b;cin>>a>>b;
	exgcd(a,b);
	x=(x%b+b)%b;//求出来的x一定满足方程,但不一定是最小解 
	cout<<x<<endl; 
	return 0;
}

六、组合数

求组合数 C ( n , m ) C(n,m) C(n,m)

模板:

LL qp(LL a,LL b){
     //是求a的b次方
    LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
    while(b>0){
     
        if(b&1ll) ans=(ans*base)%mod;
        base=(base*base)%mod;
        b>>=1ll;
    }
    return ans;
}
LL fact[N];
LL inv[N];
void init(){
     
    fact[0] = 1;
     for(int i = 1;i < N ;i ++)
       fact[i] = fact[i - 1] * i % mod;
    inv[N - 1] = qp(fact[N - 1], mod - 2);
    for(int i = N - 2; i >= 0; i --)
        inv[i] = inv[i + 1] * (i + 1) % mod;
}
LL C(LL x, LL y){
     
    if(x < y || y < 0)
        return 0;
    return fact[x] * inv[y] % mod * inv[x - y] % mod;
}
int main(){
     
	init();
	cout<<C(100,2); 
	return 0;
}

你可能感兴趣的:(#,数学,基础数论)