素数的线性筛 && 欧拉函数

O(n) 筛选素数

#include<bits/stdc++.h>
using namespace std;
const int M = 1e6 + 10 ;

int mindiv[M] ;//每个数的最小质因数
int prim[M] , pnum ;//存素数
bool vis[M] ;

void prim () {
        for (int i = 2 ; i < M ; i ++) {
                if (!vis[i]) {
                        mindiv[i] = i ;
                        prim[ pnum++ ] = i ;
                }
                for (int j = 0 ; j < pnum ; j ++) {
                        if ( i*prim[j] >= M ) break ;
                        vis[ i*prim[j] ] = 1 ;
                        mindiv[i] = prim[j] ;
                        if (i % prim[j] == 0) break ;
                }
        }
}

int main () {
        prim () ;
        return 0 ;
}

  欧拉函数O(n) :phi[i] 为<= i 的范围内与i互质的数的数量

#include<bits/stdc++.h>
using namespace std;
const int M = 1e6 + 10 ;
int mindiv[M] ;
int prim[M] , pnum ;
bool vis[M] ;
int phi[M] ; //欧拉函数

int Euler () {
        phi[1] = 1 ;
        for (int i = 2 ; i < M ; i ++) {
                if (vis[i] && phi[i] == 0) { phi[i] = pnum ; }
                if (!vis[i]) {
                        prim[ pnum++ ] = i ;
                        phi[i] = i-1 ;
                        mindiv [i] = i ;
                }
                for (int j = 0 ; j < pnum ; j ++) {
                        if (i * prim[j] >= M) break ;
                        vis[ i*prim[j] ] = 1 ;
                        mindiv [ i*prim[j] ] = prim[j] ;
                        if (i % prim[j] == 0) break ;
                        else phi[ i*prim[j] ] = phi[i] * phi[prim[j]] ;
                }
        }
}

int main () {
        Euler () ;
        return 0 ;
}

  

时间: 2024-08-02 23:18:32

素数的线性筛 && 欧拉函数的相关文章

The Euler function(线性筛欧拉函数)

/* 题意:(n)表示小于n与n互质的数有多少个,给你两个数a,b让你计算a+(a+1)+(a+2)+......+b; 初步思路:暴力搞一下,打表 #放弃:打了十几分钟没打完 #改进:欧拉函数:具体证明看po主的博客 ^0^ #超时:这里直接用欧拉函数暴力搞还是不可以的,用到线性筛欧拉函数,这里总和爆int,要用long long */ #include<bits/stdc++.h> #define ll long long using namespace std; /***********

BZOJ 2190 仪仗队(线性筛欧拉函数)

简化题意可知,实际上题目求得是gcd(i,j)=1(i,j<=n)的数对数目. 线性筛出n大小的欧拉表,求和*2+1即可.需要特判1. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # inclu

线性筛欧拉函数

#include <bits/stdc++.h> using namespace std; int P[40005]={1,1},phi[40005]; vector<int> prime; void getphi(int n){ for(int i=2;i<=n;i++){ if(!P[i])prime.push_back(i),phi[i]=i-1; for(int j=0;j<prime.size()&&prime[j]*i<=n;j++){

线性(欧拉)筛&amp;欧拉函数

线性筛法 what is 线性筛??就是基于最基本的筛法的优化. 在基础的筛法上,我们发现有的数字会被重复筛,例如6既会被2枚举到也会被3枚举到,必然有重复运算. 我们的做法就是让每一个数的最小因数筛. \(FOR\) \(EXAMPLE:\) 有一个数\(2 * 2 * 3 * 5\) 有另一个数 \(3 * 3 * 3* 5\) 那么第一个数枚举到3的话,筛到的数字是\(2 * 2 * 3 * 3 * 5\) 但是在第二个数字再次枚举的时候 枚举到2时 也会枚举到\(2 * 2 * 3 *

noip复习——线性筛(欧拉筛)

整数的唯一分解定理: \(\forall A\in \mathbb {N} ,\,A>1\quad \exists \prod _{i=1}^{s}p_{i}^{a_{i}}=A\),其中\({\displaystyle p_{1}<p_{2}<p_{3}<\cdots <p_{s}}\)而且 \(p_{i}\)是一个质数, \(a_{i}\in \mathbb {Z} ^{+}\)(摘自维基百科) 欧拉筛通过使每个整数只会被它的最小质因子筛到来保证时间复杂度,可以用来筛质数

线性求欧拉函数

我们都知道欧拉筛又称线性筛,能在O(n)的时间复杂度内筛出n以内的所有质数,而我们只要在线性筛的代码上改良一下就能求出n以内所有数的欧拉函数了.筛质数时,设外层在枚举i,内层枚举到prime[j],这时有两种情况: i%prime[j]不为0,也就是说,i与j互质,根据欧拉函数的积性可得phi[ i * prime[j] ]=phi[ i ]*phi[ prime[j] ]而这些是前面求出来的,可以直接拿来推. i%prime[j]为0,也就是说,i内有一个质因子是prime[j],不过没有关系

欧拉筛 + 欧拉函数

1 /** 2 * Fuck you. 3 * I love you too. 4 */ 5 #include<bits/stdc++.h> 6 #define lson i<<2 7 #define rson i<<2|1 8 #define LS l,mid,lson 9 #define RS mid+1,r,rson 10 #define mem(a,x) memset(a,x,sizeof(a)) 11 #define gcd(a,b) __gcd(a,b) 1

【模版】线性筛(素数,欧拉函数,莫比乌斯函数)

线性筛: 线性筛是一种比较实用的筛法,它与数论中的(完全)积性函数密切相关: (完全)积性函数的定义:对于两个整数 \(x_1\) 和 \(x_2\) ,若有函数\(f(x)\)满足:\(f(x_1x_2)=f(x_1)f(x_2)\),我们称\(f(x)\)为完全积性函数:特殊的:若 \(x_1\) 和 \(x_2\) 一定为两个互质的正整数,我们称\(f(x)\)为积性函数! 而线性筛就是利用了这一性质,将\(f(x)\)用且只用\(x\)最小的那个质因子利用\(f(x_1x_2)=f(x_

数论线性筛总结 (素数筛,欧拉函数筛,莫比乌斯函数筛,前n个数的约数个数筛)

线性筛 线性筛在数论中起着至关重要的作用,可以大大降低求解一些问题的时间复杂度,使用线性筛有个前提(除了素数筛)所求函数必须是数论上定义的积性函数,即对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数,若a,b不互质也满足的话则称作完全积性函数,下面说明每个筛子是怎么筛的. 最基础的是素数筛,其它三个筛都是以素数筛为前提 素数筛 void get_prime() { int pnum = 0; for(int i = 2;