线性筛各种函数

线性筛各种函数

线性筛素数

void make_prime(int x) {
    for(int i = 2;i <= x; i++) {
        if(!is_prime[i]) prime[++cnt] = i;
        for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
            is_prime[i * prime[j]] = 1;
            if(!(i % prime[j]))  break;
        }
    }
}

线性筛欧拉函数

void make_phi(int x) {
    phi[1] = 1;
    for(int i = 2;i <= x; i++) {
        if(!is_prime[i]) 
            phi[i] = i - 1, prime[++cnt] = i;
        for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
            is_prime[i * prime[j]] = 1;
            if(!(i % prime[j])) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}

线性筛莫比乌斯函数

void make_mu() {
    mu[1] = 1;
    for(int i = 2;i <= N - 5; i++) {
        if(!is_prime[i]) prime[++cnt] = i, mu[i] = -1;
        for(int j = 1;j <= cnt && i * prime[j] <= N - 5; j++) {
            is_prime[i * prime[j]] = 1;
            if(!(i % prime[j])) {
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }
}

线性筛约数个数

void make_r(int x) {
    r[1] = 1;
    for(int i = 2;i <= x; i++) {
        if(!is_prime[i])
            prime[++cnt] = i, r[i] = 2, num[i] = 1;
        for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
            is_prime[i * prime[j]] = 1;
            if(!(i % prime[j])) {
                num[i * prime[j]] = num[i] + 1;
                r[i * prime[j]] = r[i] / (num[i] + 1) * (num[i] + 2);
                break;
            }
            num[i * prime[j]] = 1;
            r[i * prime[j]] = r[i] * r[prime[j]];
        }
    }
}

线性筛约数和

void make_sd(int x) {
	sd[1] = sp[1] = 1;
    for(int i = 2;i <= x; i++) {
		if(!is_prime[i])
            prime[++cnt] = i, sd[i] = sp[i] = i + 1;
    	for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
			is_prime[i * prime[j]] = 1;
             if(!(i % prime[j])) {
			   sp[i * prime[j]] = sp[i] * prime[j] + 1;
                sd[i * prime[j]] = sd[i] / sp[i] * sp[i * prime[j]];
             	break;
             }
             sp[i * prime[j]] = 1 + prime[j];
             sd[i * prime[j]] = sd[i] * sd[prime[j]];
        }
    }
}

大佬讲的约数个数和约数和贼清晰

线性筛一个数的\(n\)次方

void make_id(int x) {
	id[1] = 1;
    for(int i = 2;i <= x; i++) {
		if(!is_prime[i]) prime[++cnt] = i, id[i] = ksm(i, n);
         for(int j = 1;j <= cnt && i * prime[j] <= x; j++) {
			is_prime[i * prime[j]] = 1;
             id[i * prime[j]] = id[i] * id[prime[j]] % mod;
             if(!(i % prime[j])) break;
         }
    }
}

线性筛狄利克雷卷积

​ 一般要找出\(f(p^k)\)的规律,方法就是打个表,下面以\(\phi *\mu\)为例:

void make_f() {
    f[1] = 1;
    for(int i = 2;i <= N - 5; i++) {
        if(!is_prime[i]) prime[++cnt] = i, f[i] = i - 2;
        for(int j = 1;j <= cnt && i * prime[j] <= N - 5; j++) {
            is_prime[i * prime[j]] = 1;
            if(!(i % prime[j])) {
                if((i / prime[j]) % prime[j]) f[i * prime[j]] = f[i / prime[j]] * 1ll * (prime[j] - 1) * (prime[j] - 1);
                else f[i * prime[j]] = f[i] * prime[j];
                break;
            }
            f[i * prime[j]] = f[i] * (prime[j] - 2);
        }
    }
}
posted @ 2020-09-16 21:34  C锥  阅读(201)  评论(0编辑  收藏  举报