数论板子集

威尔逊定理: p为素数,则 p ∣ ( p − 1 ) ! + 1 p\mid(p-1)!+1 p(p1)!+1,则 ( p − 2 ) ! ≡ 1 ( m o d   p ) (p-2)!\equiv1(mod\ p) (p2)!1(mod p)
欧拉定理: p,a互素,则 a ϕ ( p ) ≡ 1 ( m o d   p ) a^{\phi(p)}\equiv1(mod\ p) aϕ(p)1(mod p)
费马小定理: p为素数,则 a p ≡ a ( m o d   p ) a^p\equiv a(mod\ p) apa(mod p)
推论:p为素数,当 p ∣ a , a p − 1 ≡ 0 ( m o d   p ) p\mid a,a^{p-1}\equiv0(mod\ p) pa,ap10(mod p);当 p ∤ a , a p − 1 ≡ 1 ( m o d   p ) p\nmid a,a^{p-1}\equiv 1(mod\ p) pa,ap11(mod p)

欧几里得算法

int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
int lcm(int a,int b){
	return a/gcd(a,b)*b;
}

扩展欧几里得算法

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

欧拉筛

const int maxn=1000;
bool number[maxn+5];
int prime[maxn+5];
void euler_sieve(){
	int i,j,cnt=0;
	memset(number,true,sizeof(number));
	memset(prime,0,sizeof(prime));
	for(int i=2;i<=maxn;i++){
		if(number[i]) prime[cnt++]=i;
		for(j=0;j<cnt&&prime[j]*i<=maxn;j++){
			number[prime[j]*i]=false;
			if(i%prime[j]==0) break; 
 		}
	}
}

快速幂

ll mod_exp(ll a,ll b,ll n){
    ll res=1;
    while(b){
        if(b&1)res=mod_mul(res,a,n);
        a=mod_mul(a,a,n);
        b>>=1;
    }
    return res;
}

miller-rabin判断大素数

ll mod_mul(ll a,ll b,ll n){
    ll res=0;
    while(b){
        if(b&1)res=(res+a)%n;
        a=(a+a)%n;
        b>>=1;
    }
    return res;
}
ll mod_exp(ll a,ll b,ll n){
    ll res=1;
    while(b){
        if(b&1)res=mod_mul(res,a,n);
        a=mod_mul(a,a,n);
        b>>=1;
    }
    return res;
}
bool miller_rabin(ll n){
    if(n==2||n==3||n==5||n==7||n==11)return true;
    if(n==1||!(n%2)||!(n%3)||!(n%5)||!(n%7)||!(n%11))return false;
    ll x,pre,u;
    int i,j,k=0;
    u=n-1;
    while(!(u&1)){
        k++;u>>=1;
    }
    srand((ll)time(0));
    for(i=0;i<5;i++){//5次足够AC了
        x=rand()%(n-2)+2;
        if((x%n)==0)continue;
        x=mod_exp(x,u,n);
        pre=x;
        for(j=0;j<k;j++){
            x=mod_mul(x,x,n);
            if(x==1&&pre!=1&&pre!=n-1)return false;
            pre=x;
        }
        if(x!=1)return false;
    }
    return true;
}

求逆元
x y ≡ 1 ( m o d p ) xy\equiv1(modp) xy1(modp),则称xy互为逆元
除a取模等价于乘a逆元取模

// 扩展欧几里得法,通用
ll get_inv(ll a,ll mod){
	ll x,y;
	ll d=exgcd(a,mod,x,y);
	return d==1?(x%mod+mod)%mod:-1;
}
//费马小定理法,仅当mod为素数
ll prime_inv(ll a,ll mod){
	return mod_exp(a,mod-2,mod);
}
//线性法,用来求一组逆元
void linear_inv(int inv[],int len,int mod){
	inv[0]=inv[1]=1;
	for(int i=2;i<len;i++){
		inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	}
}

中国剩余定理

ll china(ll a[],ll b[],int n)//a[]为除数,b[]为余数
{
    ll M=1,y,x=0;
    for(int i=0;i<n;++i)
        M*=a[i];
    for(int i=0;i<n;++i)
    {
        ll w=M/a[i];
        ll tx=0;
        int t=exgcd(w,a[i],tx,y); 
        x=(x+w*(b[i]/t)*x)%M; 
    }
    return (x+M)%M;
}

组合数之打表法,N<=3000

//组合数打表模板,适用于N<=3000
//c[i][j]表示从i个中选j个的选法。
const int N=33; 
long long C[N][N];
 
void get_C(int maxn)
{
    C[0][0] = 1;
    for(int i=1;i<=maxn;i++)
    {
        C[i][0] = 1;
        for(int j=1;j<=i;j++)
            C[i][j] = C[i-1][j]+C[i-1][j-1];
            //C[i][j] = (C[i-1][j]+C[i-1][j-1])%MOD;
    }
}

组合数之求单个值 N<=2e5

#include <iostream>
#include <bits/stdc++.h>
#define maxn 200005
typedef long long ll;
using namespace std;
const ll mod=998244353;
ll fac[maxn],inv[maxn];
ll pow_mod(ll a,ll n)
{
    ll ret =1;
    while(n)
    {
        if(n&1) ret=ret*a%mod;
          a=a*a%mod;
          n>>=1;
    }
    return ret;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<maxn;i++)
    {
        fac[i]=fac[i-1]*i%mod;
    }
}
ll Cc(ll x, ll y)
{
    return fac[x]*pow_mod(fac[y]*fac[x-y]%mod,mod-2)%mod;
}
 
int main(){
    ll n,m;
    init();
    while(1){
        cin>>n>>m;
        cout<<Cc(n,m)<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值