• 【算法基础】数学知识


    质数

    质数的判定

    866. 试除法判定质数 - AcWing题库

    时间复杂度是logN

    1. #include
    2. using namespace std;
    3. int n;
    4. bool isprime(int x)
    5. {
    6. if(x<2) return false;
    7. for(int i=2;i<=x/i;i++)
    8. {
    9. if(x%i==0) return false;
    10. }
    11. return true;
    12. }
    13. signed main()
    14. {
    15. cin>>n;
    16. for(int i=1;i<=n;i++)
    17. {
    18. int x;
    19. cin>>x;
    20. if(isprime(x)) puts("Yes");
    21. else puts("No");
    22. }
    23. return 0;
    24. }

    分解质因数 

    867. 分解质因数 - AcWing题库

    1. #include
    2. using namespace std;
    3. int n;
    4. void divide(int x)
    5. {
    6. for(int i=2;i<=x/i;i++)
    7. {
    8. if(x%i==0)
    9. {
    10. int s=0;
    11. while(x%i==0) x/=i,s++;
    12. cout<" "<
    13. }
    14. }
    15. if(x>1) cout<" "<<1<
    16. cout<
    17. }
    18. signed main()
    19. {
    20. cin>>n;
    21. for(int i=1;i<=n;i++)
    22. {
    23. int x;
    24. cin>>x;
    25. divide(x);
    26. }
    27. return 0;
    28. }

     筛质数(用线性筛,O(N)

     868. 筛质数 - AcWing题库

    朴素版,埃氏筛法

    1. #include
    2. using namespace std;
    3. const int N=1e6+10;
    4. bool st[N];
    5. int prime[N],cnt;
    6. int n;
    7. void getprimes(int x)
    8. {
    9. for(int i=2;i<=x;i++)
    10. {
    11. if(st[i]) continue;
    12. prime[cnt++]=i;
    13. for(int j=i+i;j<=x;j+=i) st[j]=true;
    14. }
    15. }
    16. signed main()
    17. {
    18. cin>>n;
    19. getprimes(n);
    20. cout<
    21. return 0;
    22. }

     线性筛

    868. 筛质数 - AcWing题库

    线性筛把时间复杂度优化到O(n),就需要保证筛去一个数只用一次,保证最小质因数就可以确保这一点。

    如。筛去24,24=2*12,24=3*8,显然这里2是最小质因数,如何确保不筛去3*8?

    这里3*8=3*2*4,即i包含上一个prime,直接break。

    只要i包含了prime就不能保证最小质因数!!

    1. #include
    2. using namespace std;
    3. const int N=1e6+10;
    4. bool st[N];
    5. int prime[N],cnt;
    6. int n;
    7. void getprimes(int x)
    8. {
    9. for(int i=2;i<=x;i++)
    10. {
    11. if(!st[i]) prime[cnt++]=i;
    12. for(int j=0;prime[j]<=x/i;j++)
    13. {
    14. st[prime[j]*i]=true;
    15. if(i%prime[j]==0) break;
    16. }
    17. }
    18. }
    19. signed main()
    20. {
    21. cin>>n;
    22. getprimes(n);
    23. cout<
    24. return 0;
    25. }

    约数

    试除法求一个数的所有约束

    869. 试除法求约数 - AcWing题库

    1. #include
    2. using namespace std;
    3. void solve(int x)
    4. {
    5. stack<int> s;
    6. for(int i=1;i<=x/i;i++)
    7. {
    8. if(x%i==0)
    9. {
    10. cout<' ';
    11. if(i!=x/i) s.push(x/i);
    12. }
    13. }
    14. while(s.size())
    15. {
    16. cout<top()<<" ";
    17. s.pop();
    18. }
    19. puts("");
    20. }
    21. signed main()
    22. {
    23. int n;
    24. cin>>n;
    25. while(n--)
    26. {
    27. int x;
    28. cin>>x;
    29. solve(x);
    30. }
    31. return 0;
    32. }

     约数个数//约数之和

    870. 约数个数 - AcWing题库

    1. #include
    2. using namespace std;
    3. const int mod=1e9+7;
    4. typedef long long LL;
    5. signed main()
    6. {
    7. int n;
    8. cin>>n;
    9. unordered_map<int,int> mp;
    10. while(n--)
    11. {
    12. int x;
    13. cin>>x;
    14. for(int i=2;i<=x/i;i++)
    15. {
    16. while(x%i==0)
    17. {
    18. mp[i]++;
    19. x/=i;
    20. }
    21. }
    22. if(x>1) mp[x]++;
    23. }
    24. LL res=1;
    25. for(auto p:mp) res=res*(p.second+1)%mod;
    26. cout<
    27. return 0;
    28. }

     871. 约数之和 - AcWing题库

    1. #include
    2. using namespace std;
    3. const int mod=1e9+7;
    4. typedef long long LL;
    5. signed main()
    6. {
    7. int n;
    8. cin>>n;
    9. unordered_map<int,int> mp;
    10. while(n--)
    11. {
    12. int x;
    13. cin>>x;
    14. for(int i=2;i<=x/i;i++)
    15. {
    16. while(x%i==0)
    17. {
    18. mp[i]++;
    19. x/=i;
    20. }
    21. }
    22. if(x>1) mp[x]++;
    23. }
    24. LL res=1;
    25. for(auto p:mp)
    26. {
    27. LL a=p.first,b=p.second;
    28. LL t=1;
    29. while(b--) t=(t*a+1)%mod;//秦九韶
    30. res=res*t%mod;
    31. }
    32. cout<
    33. return 0;
    34. }

    最大公约数

    872. 最大公约数 - AcWing题库

    1. #include
    2. using namespace std;
    3. int gcb(int a,int b)
    4. {
    5. return b?gcd(b,a%b):a;
    6. }
    7. signed main()
    8. {
    9. int n;
    10. cin>>n;
    11. while(n--)
    12. {
    13. int a,b;
    14. cin>>a>>b;
    15. cout<<gcd(a,b)<
    16. }
    17. return 0;
    18. }

     
    欧拉函数 

    求任意一数的欧拉函数  O(n*sqrt(a)) 

     873. 欧拉函数 - AcWing题库

     

    1. #include
    2. using namespace std;
    3. signed main()
    4. {
    5. int n;
    6. cin>>n;
    7. while(n--)
    8. {
    9. int x;
    10. cin>>x;
    11. int res=x;
    12. for(int i=2;i<=x/i;i++)
    13. {
    14. if(x%i==0)
    15. {
    16. res=res/i*(i-1);
    17. while(x%i==0) x/=i;
    18. }
    19. }
    20. if(x>1) res=res/x*(x-1);
    21. cout<
    22. }
    23. return 0;
    24. }

    求1-n中每个数的欧拉函数  O(n)

    874. 筛法求欧拉函数 - AcWing题库

    1. #include
    2. using namespace std;
    3. const int N=1e6+10;
    4. int prime[N],cnt;
    5. bool st[N];
    6. int phi[N];//欧拉函数
    7. typedef long long LL;
    8. signed main()
    9. {
    10. int n;
    11. cin>>n;
    12. phi[1]=1;
    13. for(int i=2;i<=n;i++)
    14. {
    15. if(!st[i])
    16. {
    17. prime[cnt++]=i;
    18. phi[i]=i-1;//质数的欧拉函数
    19. }
    20. for(int j=0;prime[j]<=n/i;j++)
    21. {
    22. st[prime[j]*i]=true;
    23. if(i%prime[j]==0)
    24. {
    25. phi[prime[j]*i]=prime[j]*phi[i];
    26. //括号里质因子是一样的,只是n要多乘上一个
    27. break;
    28. }
    29. phi[prime[j]*i]=phi[i]*(prime[j]-1);
    30. //prime是质数且i不能整除prime,则说明两数没有公因数
    31. //那么prime[j]*i比i只是多了一个质因子prime[j]
    32. }
    33. }
    34. LL res=0;
    35. for(int i=1;i<=n;i++) res+=phi[i];
    36. cout<
    37. return 0;
    38. }

     快速幂

    快速幂

    875. 快速幂 - AcWing题库

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. LL qmi(int a,int b,int p)
    5. {
    6. LL res=1%p;
    7. while(b)
    8. {
    9. if(b&1) res=res*(LL)a%p;
    10. a=a*(LL)a%p;
    11. b>>=1;
    12. }
    13. return res;
    14. }
    15. signed main()
    16. {
    17. int n;
    18. cin>>n;
    19. while(n--)
    20. {
    21. int a,b,p;
    22. cin>>a>>b>>p;
    23. cout<<qmi(a,b,p)<
    24. }
    25. return 0;
    26. }

    快速幂求逆元

    876. 快速幂求逆元 - AcWing题库

    (1)当a与p互质时,用快速幂求逆元(费马小定理):quick_power(a, b, p);
    (2)当a与p不互质时,用扩展欧几里得算法求逆元:exgcd(a, p, x, y)。

    概念: 

     证明:费马小定理(通俗易懂) - 知乎 (zhihu.com)

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. LL qmi(int a,int b,int p)
    5. {
    6. LL res=1%p;
    7. while(b)
    8. {
    9. if(b&1) res=res*(LL)a%p;
    10. a=a*(LL)a%p;
    11. b>>=1;
    12. }
    13. return res;
    14. }
    15. signed main()
    16. {//当a和p不互质时无解,由于p是质数,也就只有a是p的倍数时无解
    17. int n;
    18. cin>>n;
    19. while(n--)
    20. {
    21. int a,b,p;
    22. cin>>a>>p;
    23. if(a%p==0) puts("impossible");
    24. else cout<<qmi(a,p-2,p)<
    25. }
    26. return 0;
    27. }

     扩展欧几里得算法

    扩展欧几里得算法

    877. 扩展欧几里得算法 - AcWing题库

    主要是递归。先正着求出gcd的值,求完之后倒着求x,y。

    AcWing 877. 扩展欧几里得算法 - AcWing

    1. #include
    2. using namespace std;
    3. int exgcd(int a,int b,int &x,int &y)
    4. {
    5. if(b==0)
    6. {
    7. x=1,y=0;
    8. return a;
    9. }
    10. int x1,y1,gcd;
    11. gcd=exgcd(b,a%b,x1,y1);
    12. x=y1,y=x1-a/b*y1;
    13. return gcd;
    14. }
    15. signed main()
    16. {
    17. int n;
    18. cin>>n;
    19. while(n--)
    20. {
    21. int a,b,x,y;
    22. cin>>a>>b;
    23. exgcd(a,b,x,y);
    24. cout<" "<
    25. }
    26. return 0;
    27. }

     线性同余方程

    878. 线性同余方程 - AcWing题库

    想不明白主要应该是不太清楚裴属定理,看这个:裴蜀定理 - OI Wiki (oi-wiki.org)

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. int exgcd(int a,int b,int &x,int &y)
    5. {
    6. if(b==0)
    7. {
    8. x=1,y=0;
    9. return a;
    10. }
    11. int x1,y1,gcd;
    12. gcd=exgcd(b,a%b,x1,y1);
    13. x=y1,y=x1-a/b*y1;
    14. return gcd;
    15. }
    16. signed main()
    17. {
    18. int n;
    19. cin>>n;
    20. while(n--)
    21. {
    22. int a,b,m;
    23. cin>>a>>b>>m;
    24. int x,y;
    25. int d=exgcd(a,m,x,y);
    26. if(b%d) puts("impossible");
    27. else cout<<(LL)b/d*x%m<
    28. }
    29. return 0;
    30. }

     中国剩余定理

    204. 表达整数的奇怪方式 - AcWing题库

    基础中国剩余定理:算法学习笔记(10): 中国剩余定理 - 知乎 (zhihu.com)

    好难,明天再看

    高斯消元法

    883. 高斯消元解线性方程组 - AcWing题库

    1. #include
    2. using namespace std;
    3. const int N=110;
    4. const double eps = 1e-8;
    5. int n;
    6. double a[N][N];
    7. int gauss() // 高斯消元,答案存于a[i][n]中,0 <= i < n
    8. {
    9. int c,r;//列,行
    10. for(c=0,r=0;c//遍历所有列
    11. {
    12. int t=r;//最上面一个,还没确定
    13. for(int i = r ; i < n ; i ++)
    14. {
    15. if( fabs(a[i][c]) > fabs(a[t][c]) ) t=i;//把最大的换上去
    16. }
    17. if(fabs(a[t][c])continue;//如果这个最小的是0,跳过
    18. for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);//交换
    19. for(int i=n;i>=c;i--) a[r][i]/=a[r][c]; //首位变成1
    20. for(int i=r+1;i
    21. {
    22. if(fabs(a[i][c])>eps)
    23. {
    24. for(int j=n;j>=c;j--)
    25. {
    26. a[i][j]-=a[r][j]*a[i][c];
    27. }
    28. }
    29. }
    30. r ++ ;
    31. }
    32. if(r
    33. {
    34. for(int i=r;i//从没走到的一行开始
    35. {
    36. if(fabs(a[i][n])>eps) return 2;//无解
    37. }
    38. return 1; //无穷解
    39. }
    40. //只有一解
    41. for(int i=n-1;i>=0;i--)
    42. {
    43. for(int j=i+1;j
    44. {
    45. a[i][n]-=a[i][j]*a[j][n];
    46. }
    47. }
    48. return 0;
    49. }
    50. signed main()
    51. {
    52. cin>>n;
    53. for(int i=0;i
    54. {
    55. for(int j=0;j1;j++)
    56. {
    57. cin>>a[i][j];
    58. }
    59. }
    60. int t=gauss();
    61. if (t == 2) puts("No solution");
    62. else if (t == 1) puts("Infinite group solutions");
    63. else
    64. {
    65. for (int i = 0; i < n; i ++ )
    66. printf("%.2lf\n", a[i][n]);
    67. }
    68. return 0;
    69. }

    从1开始存的版本。

    1. #include
    2. using namespace std;
    3. const int N=110;
    4. const double eps=1e-8;
    5. int n;
    6. double a[N][N];
    7. int gauss()
    8. {
    9. int r=1,c=1;//行列,r<=n,c<=n+1
    10. for(r=1,c=1;c<=n;c++) //遍历每一列
    11. {
    12. int t=r;//记录行
    13. for(int i=t;i<=n;i++)
    14. {
    15. if(fabs(a[i][c]>fabs(a[t][c]))) t=i;
    16. }
    17. if(fabs(a[t][c])continue;
    18. //走了几列同时代表确定了几行
    19. for(int i=c;i<=n+1;i++) swap(a[t][i],a[r][i]);
    20. for(int i=n+1;i>=c;i--) a[r][i]/=a[r][c];
    21. for(int i=r+1;i<=n;i++)//对每一行
    22. {
    23. if(fabs(a[i][c])continue;//如果这个是0,不操作
    24. for(int j=n+1;j>=c;j--)
    25. {
    26. a[i][j]-=a[r][j]*a[i][c];
    27. }
    28. }
    29. r++;
    30. }
    31. if(r1)
    32. {
    33. for(int i=r;i<=n;i++)
    34. {
    35. if(fabs(a[i][n+1])>eps) return 0;//无解
    36. }
    37. return 2;//无穷解
    38. }
    39. for(int i=n-1;i>=1;i--)
    40. {
    41. for(int j=i+1;j<=n+1;j++)
    42. {
    43. a[i][n+1]-=a[j][n+1]*a[i][j];
    44. }
    45. }
    46. return 1;
    47. }
    48. signed main()
    49. {
    50. cin>>n;
    51. for(int i=1;i<=n;i++)
    52. {
    53. for(int j=1;j<=n+1;j++)
    54. {
    55. cin>>a[i][j];
    56. }
    57. }
    58. int t=gauss();
    59. if(t==0) puts("No solution");
    60. else if(t==2) puts("Infinite group solutions");
    61. else
    62. {
    63. for(int i=1;i<=n;i++) printf("%.2lf\n",a[i][n+1]);
    64. }
    65. return 0;
    66. }

    884. 高斯消元解异或线性方程组 - AcWing题库

    1. #include
    2. using namespace std;
    3. const int N=110;
    4. int n;
    5. int a[N][N];
    6. void guass()
    7. {
    8. int r,c;
    9. for(r=1,c=1;c<=n;c++)//枚举列
    10. {
    11. int t=r;
    12. for(int i=r;i<=n;i++)
    13. {
    14. if(a[i][c])
    15. {
    16. t=i;
    17. break;
    18. }
    19. }
    20. if(a[t][c]==0) continue;//说明第c列都是0
    21. for(int i=c;i<=n+1;i++) swap(a[r][i],a[t][i]);
    22. for(int i=r+1;i<=n;i++)
    23. {
    24. if(a[i][c]==0) continue;
    25. for(int j=c;j<=n+1;j++)
    26. {
    27. a[i][j]^=a[r][j];
    28. }
    29. }
    30. r++;
    31. }
    32. if(r1)//说明等式左边都是0,判断等式右边即可
    33. {
    34. for(int i=r;i<=n;i++)
    35. {
    36. if(a[i][n+1]!=0)//无解
    37. {
    38. puts("No solution");
    39. return;
    40. }
    41. }
    42. puts("Multiple sets of solutions");
    43. return;
    44. }
    45. //输出结果
    46. for(int i=n-1;i>=1;i--)
    47. {
    48. for(int j=i+1;j<=n+1;j++)
    49. {
    50. a[i][n+1]^=a[i][j]*a[j][n+1];
    51. }
    52. }
    53. for(int i=1;i<=n;i++)
    54. {
    55. cout<1]<
    56. }
    57. }
    58. signed main()
    59. {
    60. cin>>n;
    61. for(int i=1;i<=n;i++)
    62. {
    63. for(int j=1;j<=n+1;j++)
    64. {
    65. cin>>a[i][j];
    66. }
    67. }
    68. guass();
    69. return 0;
    70. }

    求组合数

    885. 求组合数 I - AcWing题库

    1<=b<=a<=2000

    1. #include
    2. using namespace std;
    3. const int N=2010,mod=1e9+7;
    4. int a[N][N];
    5. void init()
    6. {
    7. for(int i=0;i
    8. {
    9. for(int j=0;j<=i;j++)
    10. {
    11. if(j==0) a[i][j]=1;
    12. else a[i][j]=(a[i-1][j]+a[i-1][j-1])%mod;
    13. }
    14. }
    15. }
    16. signed main()
    17. {
    18. init();
    19. int n;
    20. cin>>n;
    21. while(n--)
    22. {
    23. int c,b;
    24. cin>>c>>b;
    25. cout<
    26. }
    27. return 0;
    28. }

     886. 求组合数 II - AcWing题库

    1<=b<=a<=1e5

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. const int N=1e5+10,mod=1e9+7;
    5. int fact[N],infact[N];
    6. int qmi(int a,int k,int p)
    7. {
    8. int res=1;
    9. while(k)
    10. {
    11. if(k&1) res=(LL)res*a%p;
    12. a=(LL)a*a%p;
    13. k>>=1;
    14. }
    15. return res;
    16. }
    17. signed main()
    18. {
    19. fact[0]=infact[0]=1;
    20. for(int i=1;i
    21. {
    22. fact[i]=(LL)fact[i-1]*i%mod;
    23. infact[i]=(LL)infact[i-1]*qmi(i,mod-2,mod)%mod;
    24. }
    25. int n;
    26. cin>>n;
    27. while(n--)
    28. {
    29. int a,b;
    30. cin>>a>>b;
    31. cout<<(LL)fact[a]*infact[b]%mod*infact[a-b]%mod<
    32. }
    33. return 0;
    34. }

  • 相关阅读:
    华为率先商用卫星通信技术,有助中国在6G技术上取得领先优势
    git push 失败 shallow update not allowed
    【HC32L110】华大低功耗单片机启动文件详解
    es查询响应结果中获取某些字段的值
    1. 两数之和
    遥感高光谱笔记-高光谱遥感图像处理与信息提取
    好好的系统,为什么要分库分表?
    基于SSM的邮箱客户端的设计与实现
    JS运算符(算术,赋值,比较)
    面试秘籍 | 软件测试必备的mysql数据库技术
  • 原文地址:https://blog.csdn.net/m0_74183164/article/details/131863795