[关闭]
@nlogn 2019-01-22T09:55:23.000000Z 字数 2520 阅读 713

数论简记

模运算

费马小定理

内容:

为质数,且,那么

那么:
意义下的乘法逆元就是

那么如何快速求解幂呢?

两种方法:

分治快速幂

为偶数,那么

二进制快速幂

扩展欧几里得算法

求解,
当且仅当

求解

,那么令,原方程可化为,等式成立

我们知道

那么我们设

类比:

得到:

求逆元

所以求的解。

质数

一个数的因子总是成对出现,所以我们判断质数时枚举到即可。

  1. bool Is_prime(int n);
  2. {
  3. if(n==1)return false;
  4. if(n==2||n==3||n==5||n==7)return true;
  5. for(register int i=2;i*i<=n;i++)
  6. if(n%i==0)return false;
  7. return true;
  8. }

埃氏筛

一个质数的倍数一定不是质数。

  1. #include<cstring>
  2. #include<cmath>
  3. const int MAXN=1000010;
  4. bool prime[MAXN];
  5. void make_prime)()
  6. {
  7. memset(prime,true,sizeof(prime));
  8. prime[0]=prime[1]=false;
  9. int t=sqrt(MAXN);
  10. for(register int i=2;i<=t;i++)
  11. {
  12. if(prime[i])
  13. {
  14. for(register int j=2*i;j<MAXN,j+=i)
  15. {
  16. prime[j]=false;
  17. }
  18. }
  19. }
  20. return;
  21. }

欧拉筛

  1. #include<cstring>
  2. #incldue<cmath>
  3. const int MAXN=1000010;
  4. bool prime[MAXN];
  5. int Prime[MAXN];
  6. int num=0;
  7. void make_prime()
  8. {
  9. memset(prime,true,sizeof(prime));
  10. prime[0]=prime[1]=false;
  11. for(int i=2;i<=MAXN;i++)
  12. {
  13. if(prime[i])
  14. {
  15. Prime[num++]=i;
  16. }
  17. for(int j=0;j<num&&i*Prime[j]<MAXN;j++)
  18. {
  19. prime[i*Prime[j]]=false;
  20. if(!(i%Prime[j]))
  21. break;
  22. }
  23. }
  24. return;
  25. }

prime[MAXN]标记一个数是不是素数,Prime[MAXN]表示质数有哪些。

如果我们发现prime[i]为真,那么存储质数的Prime[]就要存储进一个新数i

我的数论模板

  1. inline long long gcd(long long a,long long b){//O(log n)
  2. return (!b)?a:gcd(b,a%b);
  3. }
  4. inline long long lcm(long long a,long long b){//O(log n)
  5. return a/gcd(a,b)*b/gcd(a,b);
  6. }
  7. inline long long mod(long long a,long long b,long long p){
  8. return (a%p+b)%p;
  9. }//O(1)
  10. inline void ex_gcd(int a,int b,int &c,int &x,int &y){
  11. if(!b)c=a,x=1,y=0;
  12. else{
  13. ex_gcd(b,a%b,c,y,x);
  14. y-=x*(a/b);
  15. }
  16. }
  17. inline long long quick_power1(long long a,long long b,long long p){
  18. long long ans=1;
  19. for(;n;n>>=1,a=a*a%p)if(n&1)res=res*a%p;
  20. return res;
  21. }//二进制快速幂 O(log n)
  22. inline long long quick_power2(long long a,long long b,long long p){
  23. if(n==0)return 1;
  24. if(n%2==0){
  25. long long x=quick_power2(a,n/2,p);
  26. return x*x%p;
  27. }
  28. else return a*quick_power2(a,n-1,p);
  29. }//分治快速幂 O(log n)
  30. inline long long INV_ALL(long long a,long long long p){
  31. long long GCD,tmp,res;
  32. ex_gcd(a,p,GCD,res,tmp);
  33. return mod(res,p,p);
  34. }
  35. inline long long INV_PRIME(long long a,long long p){
  36. return quick_power1(a,p-2,p);
  37. }
  38. inline void Euler(){
  39. const int MAXN=1000010;
  40. bool prime[MAXN];
  41. int Prime[MAXN],num=0;
  42. memset(prime,true,sizeof(prime));
  43. prime[0]=prime[1]=false;
  44. for(int i=2;i<=MAXN;i++){
  45. if(prime[i])Prime[num++]=i;
  46. for(int j=0;j<num&&i*Prime[j]<MAXN;j++){
  47. prime[i*Prime[j]]=false;
  48. if(!(i%Prime[j]))break;
  49. }
  50. }
  51. return;
  52. }//欧拉筛

组合数学

未完。。。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注