• 各种线性筛板子


    线性筛集合

    1.线性筛素数

    lld p[N];
    void euler(int n) {
    	bool vis[N]; memset(vis, 0, sizeof(vis));
    	for(int i = 2; i <= n; i++) {
    		if(!vis[i]) {
    			vis[i] = true; p[++tot] = i;
    		}
    		for(int j = 1; i * p[j] <= n && j <= tot; j++) {
    			vis[i * p[j]] = true;
    		}
    	}
    }
    

    2.线性筛欧拉函数 (phi)

    根据 (phi(n)) 的性质:

    1.当n为质数时,(phi(n) = n - 1)

    2.若m,n互质,(phi(n cdot m) = phi(n) cdot phi(m))

    3.若m为质数,(phi(n cdot m) = phi(n) cdot m)

    lld phi[N];
    void euler(lld n) {
    	bool vis[N]; memset(vis, 0, sizeof(vis));
    	lld p[N]; memset(p, 0, sizeof(p));
    	int tot = 0; phi[1] = 1;
    	for(int i = 2; i <= n; i++) {
    		if(!vis[i]) {
    			vis[i] = true;
    			p[++tot] = i; phi[i] = i - 1;
    		}
    		for(int j = 1; j <= tot && p[j] * i <= n; j++) {
    			vis[p[j] * i] = true;
    			if(i % p[j] != 0) phi[i * p[j]] = phi[i] * phi[p[j]];
    			else {
    				phi[i * p[j]] = phi[i] * p[j]; break;
    			}
    		}
    	}
    }
    

    一个关于欧拉函数的小性质:
    定义 (f(n)) 为小于等于n的数中,与n互质的所有数的和,则:
    (f(n) = frac{phi(n) cdot n}{2})

    证明:(gcd(n, i) = gcd(n, n - i))

    3.线性筛莫比乌斯函数 (mu)

    根据 (mu(n)) 性质:

    1.(mu(1) = 1)

    2.当n是k个不同素数之积时,(mu(n) = (-1)^k)

    3.当n存在指数大于1的质因子时,(mu(n) = 0)

    lld mu[N];
    void euler(lld n) {
    	lld p[N]; memset(p, 0, sizeof(p));
    	bool vis[N]; memset(vis, 0, sizeof(vis));
    	mu[1] = 1; int tot = 0;
    	for(int i = 2; i <= n; i++) {
    		if(!vis[i]) {
    			p[++tot] = i; vis[i] = true;
    			mu[i] = -1;
    		}
    		for(int j = 1; j <= tot && p[j] * i <= n; j++) {
    			vis[p[j] * i] = true;
    			if(i % p[j] == 0) mu[i * p[j]] = 0;
    			else mu[i * p[j]] = mu[i] * (-1);
    		}
    	}
    }
    

    4.线性筛约数个数

    (d(i)) 表示i的约数个数,(las(i)) 表示i最小的质因子的指数
    设i为任意一个数,(p[j]) 为已筛出的质数

    1.若i为质数,则(d(i) = 2, las(2) = 1)

    2.当 (i mod p[j] != 0)时,(d(i cdot p[j]) = d(i) cdot d(p[j]), las(i cdot p[j]) = 1)

    3.当 (i mod p[j] = 0)时, (d(i cdot p[j]) = d(i)/(las(i) + 1) * (las(i) + 2)),

    (las(i cdot p[j]) = las(i) + 1)

    void euler(){
    	memset(vis, 0, sizeof(vis)); d[1] = 1;
    	for(int i = 2; i <= n; i++) {
    		if(!vis[i]) {
    			vis[i] = true; p[++tot] = i;
    			d[i] = 2; las[i] = 1;
    		}
    		for(int j = 1; j <= tot && i * p[j] <= n; j++){
    			vis[i * p[j]] = true;
    			if(i % p[j] == 0){
    				d[i * p[j]] = d[i] / (las[i] + 1) * (las[i] + 2);
    				las[i * p[j]] = las[i] + 1; break;
    			}
    			else{
    				d[i * p[j]] = d[i] * d[p[j]];
    				las[i * p[j]] = 1;
    			}
    		}
    	}
    }
    

    5.线性筛约数和

    已知:(sd(i) = (1 + p_1 + p_1^2 +...+p_1^{r_1}) cdot (1 + p_2 + p_2^2 +...+p_2^{r_2}) cdot ... cdot (1 + p_k + p_k^2 +...+p_k^{r_k}))

    (sd(i)) 表示i的约数和,(num(i)) 表示最小的一项 ((1 + p_1 + p_1^2 +...+p_1^{r_1}))

    1.若i为质数,(sd(i) = i + 1, num(i) = i + 1)

    2.若 (i mod p[j] != 0), (sd(i cdot p[j]) = sd(i) cdot sd(p[j]), num(i cdot p[j]) = 1 + p[j])

    3.若 (i mod p[j] = 0), (sd(i cdot p[j]) = sd(i) / num(i) cdot (num(i) cdot p[j] + 1), num(i cdot p[j]) = num(i) cdot p[j] + 1)

    void euler() {
    	bool vis[N]; memset(vis, 0, sizeof(vis));
    	lld p[N]; memset(p, 0, sizeof(p));
    	int tot = 0; num[1] = 1; sd[1] = 1;
    	for(int i = 2; i <= n; i++) {
    		if(!vis[i]) {
    			vis[i] = true; p[++tot] = i;
    			num[i] = 1 + i; sd[i] = 1 + i;
    		}
    		for(int j = 1; j <= tot && p[j] * i <= n; j++) {
    			vis[i * p[j]] = true;
    			if(i % p[j] != 0) {
    				sd[i * p[j]] = sd[i] * sd[p[j]]; num[i * p[j]] = p[j] + 1;
    			} else {
    				num[i * p[j]] = num[i] * p[j] + 1;
    				sd[i * p[j]] = sd[i] / num[i] * num[i * p[j]];
    				break;
    			}
    		}
    	}
    }
    
    
  • 相关阅读:
    mysql性能优化
    pymysql模块
    mysql数据表约束
    MySQL数据库
    IO模型
    8451
    8946531
    6783
    256213
    27822
  • 原文地址:https://www.cnblogs.com/mcggvc/p/14306005.html
Copyright © 2020-2023  润新知