博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[模板]数学整合
阅读量:4964 次
发布时间:2019-06-12

本文共 7826 字,大约阅读时间需要 26 分钟。

数学整合:为10天后的考试准备!

 

 

1.1:欧几里得算法(位运算)

   目前接触到的最快的求GCD的算法,而且不算太长,值得一记(虽然没有什么题目卡GCD吧。。。)

1 #include
2 #include
3 #include
4 #include
5 #define man 10000000 6 #define sc(x) scanf("%d",&x) 7 using namespace std; 8 int n,x,y; 9 inline int gcd(int a,int b)10 {11 if(!a||!b)12 return a^b;13 int i=0,j=0;14 while(!(a&1))15 a>>=1,i++;16 while(!(b&1))17 b>>=1,j++;18 while(a!=b)19 {20 if(a
>=1;25 }26 return a<

 

1.2:普通版

  代码简洁,实用!

 

1 //只打出主要的部分:2 3 int gcd(int a,int b)4 {   if(b==0) return a;5      else return gcd(b,a%b);6     }

 

 

 

2:扩展欧几里得算法

   重点知识!必须牢记!还要知道各个变量的含义!

  扩展欧几里得算法实质求的是   ax+by=c=k*gcd(a,b)

  所以我们求的是   ax+by=gcd(a,b)

  求出之后判断    c%gcd(a,b)是否等于0

  若不能被整除,则代表无解;

  若ax+by=gcd(a,b)的解为(x,y),ax+by=c的解(x,y)=(c/gcd(a,b)*x, c/gcd(a,b)*y)

 

1 #include
2 #define man 110000 3 #define sc(x) scanf("%lld",&x) 4 #define LL long long 5 using namespace std; 6 LL a,b,k,x,y; 7 LL exgcd(LL a,LL b,LL &x,LL &y) 8 { 9 if(b==0)10 {11 x=1;y=0;12 return a;13 }14 else15 {16 LL ret=exgcd(b,a%b,x,y);17 LL t=x;18 x=y;19 y=t-(a/b)*y;20 return ret;21 }22 }23 int main()24 {25 sc(a);sc(b);sc(k);26 LL d=exgcd(a,b,x,y);27 if(k%d!=0)28 printf("No\n");29 else 30 {31 x=x*(k/d);32 y=(k-a*x)/b;33 cout<
<<" "<
<

 

3:快速幂

  这个实在没什么好讲的了。。。

1 #include
2 #define sc(x) scanf("%d",&x) 3 using namespace std; 4 int n,m; 5 int p,ans=1; 6 void bPow(int a,int b,int p)//Binary_Pow 7 { int base=a; 8 while(b) 9 {10 if(b&1) ans=ans%p*base;11 base=base*base%p;12 b>>=1;13 }14 }15 int main()16 {17 sc(n);sc(m);sc(p);18 bPow(n,m,p);19 cout<
<

 

4:快速乘

  也没什么讲的,就是把快速幂的乘号变成加号(效率不错)

1 //快速乘相当于乘法,例 3 5 10 =3*5%10 2 #include
3 #define sc(x) scanf("%d",&x) 4 using namespace std; 5 int n,m; 6 int p,ans=0; 7 void bAdd(int a,int b,int p) 8 { int base=a; 9 while(b)10 {11 if(b&1) ans=(ans+base)%p;12 base=(base+base)%p;13 b>>=1;14 }15 }16 int main()17 {18 sc(n);sc(m);sc(p);19 bAdd(n,m,p);20 cout<
<

 

5.乘法逆元    a*n ≡ 1(mod p)

  5.1当p为素数时,我们可以直接使用费马小定理操作:

  使用快速幂

#include
using namespace std;inline long long bpow(long long a,long long b,long long mod){ long long base=a,ans=1; while(b) { if(b&1) ans=(ans*base)%mod; base=(base*base)%mod; b>>=1; } return ans; } void write(long long z)//快输{ char r[1001011]; long long len=0; if(!z) { putchar(48); putchar('\n'); return; } for(;z;z/=10)r[++len]=z%10; while(len)putchar(r[len--]+48); putchar('\n');}long long n,p;int main(){ scanf("%lld%lld",&n,&p); for(long long i=1;i<=n;i++) write(bpow(i,p-2,p)); return 0; }

 

  5.2使用线性递推式进行求解

  可以参照 洛谷 P3811

#include
using namespace std;long long inv[3000010];long long n,p;int main(){ scanf("%lld%lld",&n,&p); inv[1]=1; printf("1\n"); for(int i=2;i<=n;i++) inv[i]=(p-(p/i))*inv[p%i]%p,printf("%lld\n",inv[i]);//需牢记递推式 return 0; }

  5.3使用欧几里得算法进行求解

  实质求    ax+py=1    中的 x

 

1 #include
2 #include
3 #include
4 using namespace std; 5 int n,mod; 6 inline int read() 7 { 8 char c=getchar();int flag=1,x=0; 9 while(c<'0'||c>'9') {
if(c=='-') flag=-1;c=getchar();}10 while(c>='0'&&c<='9') x=x*10+c-48,c=getchar(); return x*flag;11 }12 int x,y;13 int exgcd(int a,int b,int &x,int &y)14 {15 if(b==0)16 {17 x=1,y=0;18 return a;19 }20 int r=exgcd(b,a%b,x,y);21 int tmp=x;x=y;y=tmp-(a/b)*y;22 return r;23 }24 int main()25 {26 n=read(),mod=read();27 for(int i=1;i<=n;i++)28 {29 int g=exgcd(i,mod,x,y);30 while(x<0) x+=mod;31 printf("%d\n",x);32 }33 return 0;34 }

 

6.欧拉函数

  欧拉函数其实较好理解,但需要记住一些结论

  摘自:

 欧拉函数详解  1.对一个正整数N,欧拉函数是小于N且与N互质的数的个数.。  2.例如φ(24)=8,因为1, 5, 7, 11, 13, 17, 19, 23均和 24 互质。  3.φ(n) = n*(1-1/p1)*(1-1/p2)*......(1-1/pn)   其中(p1.....pn)为N的素因子欧拉函数的基本性质:    ① N是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)    ② 除了N=2,φ(N)都是偶数.    ③ 小于N且与N互质的所有数的和是φ(n)*n/2。//感觉很重要...但又感觉用不到    ④ 欧拉函数是积性函数——若m,n互质,φ(m*n)=φ(m)*φ(n)。    ⑤ 当N为奇数时,φ(2*N)=φ(N)    ⑥ 若N是质数p的k次幂,φ(N)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟N互质。    ⑦ 当N是质数时,φ(N) = N-1

 

 代码:

1 #include
2 #define man 110000 3 #define sc(x) scanf("%d",&x) 4 #define LL long long 5 using namespace std; 6 int n; 7 int p[man]; 8 inline void ola() 9 {10 for(int i=1;i<=n;i++)11 p[i]=i;12 for(int i=2;i<=n;i++)13 {14 if(p[i]==i)15 {16 for(int j=i;j<=n;j+=i)17 p[j]=p[j]/i*(i-1);//或p[j]-=p[j]/i;18 }19 }20 }21 int main()22 {23 sc(n);24 ola();25 for(int i=1;i<=n;i++)26 cout<
<<" "<
<

 

1 inline int euler(int n) 2 {    int ret=n; 3     for(int i=2;i*i<=n;i++) 4     {    if(n%i==0) 5         {    ret-=ret/i; 6             while(n%i==0) 7                 n/=i; 8             } 9         }10     if(n>1)11          ret-=ret/n;12     return ret;13     }

 

   

  7.线性筛素数

  这也是考试的时候不能打错的函数。十分重要的函数。

1 #include
2 #include
3 #include
4 #include
5 #include
6 #define man 10000000 7 using namespace std; 8 int n,isprime[man],prime[man],p=0; 9 inline void calcprime()10 {11 for(int i=2;i<=n;i++)12 {13 if(isprime[i]==0)14 { 15 prime[++p]=i;16 }17 for(int j=1;i*prime[j]<=n;j++)18 { 19 isprime[i*prime[j]]=1;20 if(i%prime[j]==0)21 break;22 }23 } 24 }25 int main()26 { 27 memset(isprime,0,sizeof(isprime));28 memset(prime,0,sizeof(prime));29 cin>>n;30 calcprime();31 for(int i=1;i<=p;i++)32 cout<
<

 

8.线性筛欧拉函数与素数

  很强大。。。

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 typedef long long ll; 7 const int N=1e7+5; 8 int n; 9 bool vis[N];10 int p[N],m=0;11 ll s[N],ans,phi[N];12 void sieve(){13 phi[1]=1;14 for(int i=2;i<=n;i++){15 if(!vis[i]){16 p[++m]=i;17 phi[i]=i-1;18 }19 for(int j=1;j<=m&&i*p[j]<=n;j++){20 vis[i*p[j]]=1;21 if(i%p[j]==0){22 phi[i*p[j]]=phi[i]*p[j];23 break;24 }25 phi[i*p[j]]=phi[i]*(p[j]-1);26 }27 }28 for(int i=1;i<=n;i++) s[i]=s[i-1]+phi[i];29 }30 int main(){31 scanf("%d",&n);32 sieve();33 for(int i=1;i<=m;i++) ans+=s[n/p[i]];34 printf("%lld",ans*2-m);35 }

 

 

9.同余方程组(中国剩余定理)

注意:下面是洛谷典型的中国剩余定理的题目(洛谷P1495 曹冲养猪)的代码

   但我是用同余方程组解的。

   代码中同余方程为:P≡b(mod m)

  

1 #include
2 using namespace std; 3 #define ll long long 4 inline ll read() 5 { ll x=0;bool f=0;char ch=getchar(); 6 while(!isdigit(ch)){ f=(ch==45);ch=getchar();} 7 while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 8 return f?(~x+1):x; 9 }10 ll n,x,y;11 ll b1,b2,m1,m2;12 ll exgcd(ll a,ll b,ll &x,ll &y)13 { if(b==0)14 { x=1;y=0;return a;}15 ll ret=exgcd(b,a%b,x,y);16 ll t=x;x=y;y=t-(a/b)*y;17 return ret;18 }19 int main()20 { n=read();21 m1=read();b1=read();22 for(int i=1;i

 

 

 

   

转载于:https://www.cnblogs.com/Slager-Z/p/7769467.html

你可能感兴趣的文章
ThinkPHP中:RBAC权限控制的实习步骤
查看>>
[转](.NET Core C#) AES Encryption
查看>>
[转]EntityFramework中常用的数据修改方式
查看>>
[转]SQL Collation冲突解决 临时表
查看>>
[转]Gitlab-CI持续集成之Runner配置和CI脚本
查看>>
Spark&Hive结合起来
查看>>
使用Flex和java servlet上传文件
查看>>
软件工程的实践项目课程的自我目标
查看>>
POJ 1321 棋盘问题 (深搜)
查看>>
自定义TabBar
查看>>
最近戴着眼镜坐电脑前总是不自觉的眼痛就搜了下怎么保护眼睛无意中看到了这篇文章希望广大爱好编程的朋友多注意保护自己的眼睛!!...
查看>>
Eclipse快捷键大全
查看>>
Let's Chat ZOJ - 3961
查看>>
该不该主动去联系多年未联系的老同学?看完这篇文章你再回答
查看>>
业务逻辑漏洞个人经验集锦【不定时更新~】
查看>>
[Swift] Storyboard outlet and action
查看>>
[Compose] 10. Capture Side Effects in a Task
查看>>
[Javascript AST] 0. Introduction: Write a simple BabelJS plugin
查看>>
[Core Javascirpt] Basic Metaprogramming: Dynamic Method
查看>>
[Angular2 Router] Use Params from Angular 2 Routes Inside of Components
查看>>