标签:说明 algo algorithm 最小 区间 递归 扩展欧几里得 write 因此
辗转相除法
1.求最大公约数
1 #include <cstdio> 2 #include <cctype> 3 #include <cmath> 4 #define num s-‘0‘ 5 using namespace std; 6 7 int x1,x2,y1,y2; 8 9 void read(int &x){ 10 char s; 11 x=0; 12 bool flag=0; 13 while(!isdigit(s=getchar())) 14 (s==‘-‘)&&(flag=true); 15 for(x=num;isdigit(s=getchar());x=x*10+num); 16 (flag)&&(x=-x); 17 } 18 19 void write(int x) 20 { 21 if(x<0) 22 { 23 putchar(‘-‘); 24 x=-x; 25 } 26 if(x>9) 27 write(x/10); 28 putchar(x%10+‘0‘); 29 } 30 31 int gcd(int, int); 32 33 int main() 34 { 35 read(x1);read(y1);read(x2);read(y2); 36 write(gcd(abs(x1-x2),abs(y1-y2))-1); 37 } 38 39 int gcd(int x, int y) 40 { 41 if (y==0) return x; 42 return gcd(y, x%y); 43 }
2.扩展欧几里得算法
1 #include <cstdio> 2 #include <cctype> 3 #include <cmath> 4 #define num s-‘0‘ 5 using namespace std; 6 7 int a,b,x,y; 8 9 void read(int &x){ 10 char s; 11 x=0; 12 bool flag=0; 13 while(!isdigit(s=getchar())) 14 (s==‘-‘)&&(flag=true); 15 for(x=num;isdigit(s=getchar());x=x*10+num); 16 (flag)&&(x=-x); 17 } 18 19 void write(int x) 20 { 21 if(x<0) 22 { 23 putchar(‘-‘); 24 x=-x; 25 } 26 if(x>9) 27 write(x/10); 28 putchar(x%10+‘0‘); 29 } 30 31 int exgcd(int, int, int&, int&); 32 33 int main() 34 { 35 read(a);read(b); 36 write(exgcd(a,b,x,y)); 37 putchar(‘\n‘); 38 write(x); 39 putchar(‘ ‘); 40 write(y); 41 } 42 43 int exgcd(int a, int b, int &x, int &y) 44 { 45 int d=a; 46 if (b != 0) 47 { 48 d=exgcd(b, a%b, y, x); 49 y-=(a/b)*x; 50 } 51 else 52 { 53 x=1; y=0; 54 } 55 return d; 56 }
有关素数的基本算法
1.素数测试
1 #include <cstdio> 2 #include <cctype> 3 #include <vector> 4 #include <map> 5 #define num s-‘0‘ 6 using namespace std; 7 8 int n; 9 10 void read(int &x){ 11 char s; 12 x=0; 13 bool flag=0; 14 while(!isdigit(s=getchar())) 15 (s==‘-‘)&&(flag=true); 16 for(x=num;isdigit(s=getchar());x=x*10+num); 17 (flag)&&(x=-x); 18 } 19 20 void write(int x) 21 { 22 if(x<0) 23 { 24 putchar(‘-‘); 25 x=-x; 26 } 27 if(x>9) 28 write(x/10); 29 putchar(x%10+‘0‘); 30 } 31 32 bool is_prime(int n);//素性测试 33 vector<int> divisor(int);//约数枚举 34 map<int, int> prime_factor(int);//整数分解 35 36 int main() 37 { 38 read(n); 39 if (is_prime(n)) puts("true"); 40 else puts("false"); 41 vector<int> v=divisor(n); 42 map<int, int> m=prime_factor(n); 43 for (int i=0; i<v.size(); i++) 44 { 45 write(v[i]);putchar(‘ ‘); 46 } 47 putchar(‘\n‘); 48 for (map<int, int>::iterator ite=m.begin(); ite!=m.end(); ite++) 49 { 50 write(ite->first);printf(": ");write(ite->second);putchar(‘\n‘); 51 } 52 } 53 54 bool is_prime(int n)//素性测试 55 { 56 for (int i=2; i*i<=n; i++) 57 { 58 if (n%i==0) return false; 59 } 60 return n!=1;//1是个例外 61 } 62 63 vector<int> divisor(int n)//约数枚举 64 { 65 vector<int> res; 66 for (int i=1; i*i<=n; i++) 67 { 68 if (n%i==0) 69 { 70 res.push_back(i); 71 if (i!=n/i) res.push_back(n/i); 72 } 73 } 74 return res; 75 } 76 77 map<int, int> prime_factor(int n)//整数分解 78 { 79 map<int, int> res; 80 for (int i=2; i*i<=n; i++) 81 { 82 while (n%i==0) 83 { 84 ++res[i]; 85 n/=i; 86 } 87 } 88 if (n>1) ++res[n]; 89 return res; 90 }
2.埃氏筛法
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 const int MAX_N=1000000; 8 int n; 9 bool is_prime[MAX_N+1]; 10 int prime[MAX_N]; 11 int p=0; 12 13 void read(int &x){ 14 char s; 15 x=0; 16 bool flag=0; 17 while(!isdigit(s=getchar())) 18 (s==‘-‘)&&(flag=true); 19 for(x=num;isdigit(s=getchar());x=x*10+num); 20 (flag)&&(x=-x); 21 } 22 23 void write(int x) 24 { 25 if(x<0) 26 { 27 putchar(‘-‘); 28 x=-x; 29 } 30 if(x>9) 31 write(x/10); 32 putchar(x%10+‘0‘); 33 } 34 35 int sieve(int); 36 37 int main() 38 { 39 read(n); 40 write(sieve(n));putchar(‘\n‘); 41 for (int i=1; i<=p; i++) 42 { 43 write(prime[i]);putchar(‘ ‘); 44 if (i%10==0) putchar(‘\n‘); 45 } 46 } 47 48 int sieve(int n) 49 { 50 fill(is_prime, is_prime+(n+1), true); 51 fill(prime, prime+n, 0); 52 is_prime[0]=is_prime[1]=false; 53 for (int i=2; i<=n; i++) 54 { 55 if (is_prime[i]) 56 { 57 prime[++p]=i; 58 for (int j=2*i; j<=n; j+=i) 59 is_prime[j]=false; 60 } 61 } 62 return p; 63 }
埃氏筛法的复杂度O(nloglogn) ,可近似看成线性的,下面补充一种线性筛法
补充:欧拉筛法
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 const int MAX_N=1000000; 8 int n; 9 bool is_prime[MAX_N+1]; 10 int prime[MAX_N]; 11 int p=0; 12 13 void read(int &x){ 14 char s; 15 x=0; 16 bool flag=0; 17 while(!isdigit(s=getchar())) 18 (s==‘-‘)&&(flag=true); 19 for(x=num;isdigit(s=getchar());x=x*10+num); 20 (flag)&&(x=-x); 21 } 22 23 void write(int x) 24 { 25 if(x<0) 26 { 27 putchar(‘-‘); 28 x=-x; 29 } 30 if(x>9) 31 write(x/10); 32 putchar(x%10+‘0‘); 33 } 34 35 int sieve(int); 36 37 int main() 38 { 39 read(n); 40 write(sieve(n));putchar(‘\n‘); 41 for (int i=1; i<=p; i++) 42 { 43 write(prime[i]);putchar(‘ ‘); 44 if (i%10==0) putchar(‘\n‘); 45 } 46 } 47 48 int sieve(int n) 49 { 50 fill(is_prime, is_prime+(n+1), true); 51 fill(prime, prime+n, 0); 52 is_prime[0]=is_prime[1]=false; 53 for (int i=2; i<=n; i++) 54 { 55 if (is_prime[i]) 56 { 57 prime[++p]=i; 58 } 59 for (int j=1; j<=p; j++) 60 { 61 if (prime[j]>n/i) break; 62 is_prime[i*prime[j]]=false; 63 if (i%prime[j]==0) break; 64 } 65 } 66 return p; 67 }
补充:欧拉函数
φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*…*(1-1/pn) 其中p1,p2…pn为x的所有质因数;x是正整数;
φ(1)=1(唯一和1互质的数,且小于等于1)。
注意:每种质因数只有一个
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 const int MAX_N=1000000; 8 int n; 9 bool is_prime[MAX_N+1]; 10 int prime[MAX_N]; 11 int p=0; 12 int phi[MAX_N+1]; 13 14 void read(int &x){ 15 char s; 16 x=0; 17 bool flag=0; 18 while(!isdigit(s=getchar())) 19 (s==‘-‘)&&(flag=true); 20 for(x=num;isdigit(s=getchar());x=x*10+num); 21 (flag)&&(x=-x); 22 } 23 24 void write(int x) 25 { 26 if(x<0) 27 { 28 putchar(‘-‘); 29 x=-x; 30 } 31 if(x>9) 32 write(x/10); 33 putchar(x%10+‘0‘); 34 } 35 36 void euler(int); 37 38 int main() 39 { 40 read(n); 41 euler(n);putchar(‘\n‘); 42 for (int i=1; i<=n; i++) 43 { 44 write(phi[i]);putchar(‘ ‘); 45 if (i%10==0) putchar(‘\n‘); 46 } 47 } 48 49 void euler(int n) 50 { 51 fill(is_prime, is_prime+(n+1), true); 52 fill(prime, prime+n, 0); 53 fill(phi, phi+(n+1), 0); 54 is_prime[0]=is_prime[1]=false; 55 phi[1]=1; 56 for (int i=2; i<=n; i++) 57 { 58 if (is_prime[i]) 59 { 60 prime[++p]=i; 61 phi[i]=i-1; 62 } 63 for (int j=1; j<=p; j++) 64 { 65 if (prime[j]>n/i) break; 66 is_prime[i*prime[j]]=false; 67 if (i%prime[j]==0) 68 { 69 phi[i*prime[j]]=phi[i]*prime[j]; 70 break; 71 } 72 else 73 { 74 phi[i*prime[j]]=phi[i]*phi[prime[j]]; 75 } 76 } 77 } 78 }
②直接求φ(n),利用公式
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 const int MAX_N=1000000; 8 int n; 9 10 void read(int &x){ 11 char s; 12 x=0; 13 bool flag=0; 14 while(!isdigit(s=getchar())) 15 (s==‘-‘)&&(flag=true); 16 for(x=num;isdigit(s=getchar());x=x*10+num); 17 (flag)&&(x=-x); 18 } 19 20 void write(int x) 21 { 22 if(x<0) 23 { 24 putchar(‘-‘); 25 x=-x; 26 } 27 if(x>9) 28 write(x/10); 29 putchar(x%10+‘0‘); 30 } 31 32 int phi(int); 33 34 int main() 35 { 36 read(n); 37 write(phi(n));putchar(‘\n‘); 38 } 39 40 int phi(int n) 41 { 42 int res=n; 43 for (int i=2; i*i<=n; i++) 44 { 45 if (n%i==0) 46 { 47 res=res*(i-1)/i; 48 while (n%i==0) n=n/i; 49 } 50 } 51 if (n>1) res=res*(n-1)/n; 52 return res; 53 }
3.区间筛法
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 const int MAX_L=1000000; 8 long long a,b; 9 bool is_prime_small[MAX_L]; 10 bool is_prime[MAX_L]; 11 12 int max(int x, int y) 13 { 14 if (x>y) return x; 15 return y; 16 } 17 18 void read(long long &x){ 19 char s; 20 x=0; 21 bool flag=0; 22 while(!isdigit(s=getchar())) 23 (s==‘-‘)&&(flag=true); 24 for(x=num;isdigit(s=getchar());x=x*10+num); 25 (flag)&&(x=-x); 26 } 27 28 void write(long long x) 29 { 30 if(x<0) 31 { 32 putchar(‘-‘); 33 x=-x; 34 } 35 if(x>9) 36 write(x/10); 37 putchar(x%10+‘0‘); 38 } 39 40 void segment_sieve(); 41 42 int main() 43 { 44 read(a);read(b); 45 segment_sieve(); 46 for (int i=0; i<b-a; i++) 47 { 48 if (is_prime[i] && i+a!=0 && i+a!=1) 49 { 50 write(i+a); 51 putchar(‘ ‘); 52 } 53 } 54 } 55 56 void segment_sieve() 57 { 58 fill(is_prime_small, is_prime_small+b, true); 59 fill(is_prime, is_prime+(b-a), true); 60 for (int i=2; (long long)i*i<b; i++) 61 { 62 if (is_prime_small[i]) 63 { 64 for (int j=2*i; (long long)j*j<b; j+=i) 65 is_prime_small[j]=false; 66 for (long long j=max(2LL, (a+i-1)/i)*i; (long long)j<b; j+=i) 67 is_prime[j-a]=false; 68 } 69 } 70 }
快速幂
O(logn)时间内完成幂运算
两种写法:
①将n拆解成2的幂次
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 long long x,n,mod; 8 9 void read(long long &x){ 10 char s; 11 x=0; 12 bool flag=0; 13 while(!isdigit(s=getchar())) 14 (s==‘-‘)&&(flag=true); 15 for(x=num;isdigit(s=getchar());x=x*10+num); 16 (flag)&&(x=-x); 17 } 18 19 void write(long long x) 20 { 21 if(x<0) 22 { 23 putchar(‘-‘); 24 x=-x; 25 } 26 if(x>9) 27 write(x/10); 28 putchar(x%10+‘0‘); 29 } 30 31 long long mod_pow(long long, long long, long long); 32 33 int main() 34 { 35 read(x);read(n);read(mod); 36 write(mod_pow(x,n,mod)); 37 putchar(‘ ‘); 38 } 39 40 long long mod_pow(long long x, long long n, long long mod) 41 { 42 long long res=1; 43 while (n>0) 44 { 45 if (n & 1) res=res*x % mod; 46 x=x*x%mod; 47 n >>= 1; 48 } 49 return res; 50 }
②递归求解
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define num s-‘0‘ 5 using namespace std; 6 7 long long x,n,mod; 8 void read(long long &x){ 9 char s; 10 x=0; 11 bool flag=0; 12 while(!isdigit(s=getchar())) 13 (s==‘-‘)&&(flag=true); 14 for(x=num;isdigit(s=getchar());x=x*10+num); 15 (flag)&&(x=-x); 16 } 17 18 void write(long long x) 19 { 20 if(x<0) 21 { 22 putchar(‘-‘); 23 x=-x; 24 } 25 if(x>9) 26 write(x/10); 27 putchar(x%10+‘0‘); 28 } 29 30 long long mod_pow(long long, long long, long long); 31 32 int main() 33 { 34 read(x);read(n);read(mod); 35 write(mod_pow(x,n,mod)); 36 putchar(‘ ‘); 37 } 38 39 long long mod_pow(long long x, long long n, long long mod) 40 { 41 if (n==0) return 1; 42 long long res=mod_pow(x*x%mod, n/2, mod); 43 if (n & 1) res=res*x%mod; 44 return res; 45 }
标签:说明 algo algorithm 最小 区间 递归 扩展欧几里得 write 因此
原文地址:https://www.cnblogs.com/Ymir-TaoMee/p/9463743.html