码迷,mamicode.com
首页 > 其他好文 > 详细

数学瞎整理

时间:2018-10-19 14:10:53      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:线性   mod   efi   ble   amp   扫描   ack   a*   lan   

一.质数

 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

   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 }

 

数学瞎整理

标签:线性   mod   efi   ble   amp   扫描   ack   a*   lan   

原文地址:https://www.cnblogs.com/kylara/p/9814360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!