数学瞎整理
Posted kylara
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学瞎整理相关的知识,希望对你有一定的参考价值。
一.质数
1.筛质数:有两种 一个线性筛,一个欧拉筛。一般用欧拉筛就行了,如果是求一个[l,r] l r大但差的绝对值小的区间,先用线性筛筛前面,然后用欧拉筛筛后面
欧拉筛O(N log log N):注意每次i循环从2开始 j从i开始
1 bool v[N]; 2 int n; 3 void prime(int n) 4 { 5 memset(v,0,sizeof(v)); 6 for(int i=2;i<=n;i++) 7 { 8 if(v[i]) continue; 9 cout<<i<<" "; 10 for(int j=1;j<=n/i;j++) v[i*j]=1; 11 } 12 }
线性筛 O(N):j从1开始
1 void primes(int n) 2 { 3 memset(v,0,sizeof(v)); 4 cnt=0; 5 for(int i=2;i<=n;i++) 6 { 7 if(!v[i]) prime[++cnt]=i,v[i]=i; 8 for(int j=1;j<=cnt;j++) 9 { 10 if(prime[j]>v[i]||prime[j]>n/i) break; 11 v[i*prime[j]]=prime[j]; 12 } 13 } 14 for(int i=1;i<=cnt;i++) 15 cout<<prime[i]<<" "; 16 }
2.质因数分解:试除法。 结合欧拉筛,扫描2~ √N的每个数d, 若d整除N,从N中除掉所有因子d,同时累计除去的d的个数。
1 void divide(int n) 2 { 3 cnt=0; 4 for(int i=2;i*i<=n;i++) 5 { 6 if(n%i==0) 7 { 8 prime[++cnt]=i; c[cnt]=0; 9 while(n%i==0) n/=i,c[cnt]++; 10 } 11 } 12 if(n>1) prime[++cnt]=n,c[cnt]=1; 13 for(int i=1;i<=cnt;i++) 14 cout<<prime[i]<<"^"<<c[i]<<endl; 15 }
3.example
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define N 10000010 4 #define mod 998244353 5 using namespace std; 6 ll prime[N],cnt,v[N]; 7 ll L,R,ans,ans2; 8 void pre() 9 { 10 for(int i=2;i<1000000;i++) 11 { 12 if(v[i]==0) v[i]=i,prime[++cnt]=i; 13 for(int j=1;j<=cnt;j++) 14 { 15 if(prime[j]>v[i]||prime[j]>1000000/i) break; 16 v[i*prime[j]]=prime[j]; 17 } 18 } 19 } 20 int main() 21 { 22 pre(); 23 scanf("%lld%lld",&L,&R); 24 memset(v,0,sizeof(v)); 25 for(ll i=1;i<=cnt;i++) 26 { 27 ll st=max(1ll,(L-1)/prime[i])*prime[i]+prime[i]; 28 for(ll j=st;j<=R;j+=prime[i]) 29 { 30 if(v[j-L]) continue; 31 v[j-L]=1; 32 ans++; 33 ans2=(ans2+prime[i])%mod; 34 } 35 } 36 printf("%lld %lld",ans,ans2); 37 return 0; 38 }
二.约数
-
求约数(集合)
1.试除法:略
有一推论:一个整数N的约数个数上界为2√N
2.倍数法
推论:1~N每个数的约数个数的总和约为 N log N
1 vector<int> f[N]; 2 int n; 3 void pu(int n) 4 { 5 for(int i=1;i<=n;i++) 6 for(int j=1;j<=n/i;j++) 7 f[i*j].push_back(i); 8 for(int i=1;i<=n;i++){ 9 for(int j=0;j<f[i].size();j++) 10 cout<<f[i][j]<<" "; 11 cout<<endl; 12 } 13 }
3.example 反素数
见P134
1 #include<bits/stdc++.h> 2 #define N 2000000000 3 #define ll long long 4 using namespace std; 5 ll n; 6 ll ans; 7 int num=1; 8 int a[11]={0,2,3,5,7,11,13,17,19,23,29}; 9 void dfs(int dep,int dex,ll anss,int cnt) 10 { 11 if(dep==10) 12 { 13 if((anss>ans&&cnt>num)||(anss<=ans&&cnt>=num)) 14 { 15 ans=anss; 16 num=cnt; 17 } 18 return; 19 } 20 int t=1; 21 for(int i=0;i<=dex;i++) 22 { 23 dfs(dep+1,i,anss*t,cnt*(i+1)); 24 t*=a[dep]; 25 if(anss*t>n) break; 26 } 27 } 28 int main() 29 { 30 scanf("%lld",&n); 31 dfs(1,30,1,1); 32 printf("%lld ",ans); 33 return 0; 34 }
-
gcd
1.定理:
-
gcd(a,b)*lcm(a,b)=a*b
-
gcd(a,b)=gcd(b,a-b)=gcd(a,a-b) (a>=b)
- gcd(a,b)=gcd(b,a mod b) (b!=0)
2.一行gcd:
1 int gcd(int a,int b) 2 { 3 return b?gcd(b,a%b):a; 4 }
以上是关于数学瞎整理的主要内容,如果未能解决你的问题,请参考以下文章