1. 程式人生 > >數學瞎整理

數學瞎整理

一.質數

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\n",ans);
33     return 0;
34 }
  • gcd