4.数论

$\sqrt n$筛质因子
只能存在一个质因子大于sqrt(n),可能不存在

    rep(i , 2, tmp) {   
        while(x % i == 0) x /= i;//如果x % i == 0,那么i为x的一个质因子
    }
    if(x > 1)//还存在一个质因子大于sqrt(x)

2.对于一个正整数N的素数幂分解N=$P_1^{q_1}P_2^{q_2}...P_n^{q_n}.$
$ φ(N)=N
(1-1/P1)(1-1/P2)...*(1-1/Pn)$.

int phi(int x)  
{  
    int ans = x,qwq = sqrt(x);  
    rep(i,2,qwq)
        if(x % i == 0) {  
            ans = ans - ans / i;  
            while(x % i == 0)  x /= i;   
        }  
    if(x > 1)  ans = ans - ans / x;
    return ans;  
}  

3.线性筛素数
因为phi函数是一个积性函数,所以可以线性筛出
如果$i$为质数,那么phi[i] = i - 1
否则可以通过积性函数的性质求出。

void work() {
    phi[1] = 1;
    vis[1] = 1;
    rep(i , 2, n) {
        if(!vis[i]) prime[++ num] = i,phi[i] = i - 1;
        for(int j = 1;j <= num && i * prime[j] <= n;++ j) {
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}

4.n!在modp意义下的逆元
n!的逆元

inv[i] = inv[i + 1] * (i + 1) % p//i表示i!

5.杨辉三角求组合数
$C(n,m) = C(n - 1,m) + C(n - 1,m - 1)$

for(int i = 0;i <= 2000;++ i) 
        f[i][0] = 1;
for(int i = 1;i <= 2000;++ i) {
    for(int j = 1;j <= i;++ j) {
        f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % k;
        if(!f[i][j]) sum[i][j] ++;
    }
}

6.gcd(最大公因数)

int gcd(int a,int b) {return !b ? a : gcd(b , a % b);}

7.筛最小质因子

void get() {
    vis[1] = 1;
    for(int i = 2;i <= n;++ i) {
        if(!vis[i]) {prime[++ num] = i;v[i] = i;}
        for(int j = 1;i * prime[j] <= n && j <= num;++ j) {
            vis[i * prime[j]] = true;
            v[i * prime[j]] = prime[j];
            if(i % prime[j] == 0) break;
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/gzygzy/p/9931248.html