基础数学知识学习笔记

一、分解质因数

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,int b){
    ll ans=1ll%mod;
    while(b>0){
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
ll fact[N],inv[N];
ll C(ll x, ll y){
    if(x<y||y<0) return 0;
    return fact[x]*inv[y]%mod*inv[x-y]%mod;
}
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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值