基础数论模版
来源:互联网 发布:淘宝指数查询官网 编辑:程序博客网 时间:2024/05/19 16:20
欧拉函数值,小于n且与n互质的数的个数
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>using namespace std;const int maxn = 1000005;int p[maxn];//m[i]保存i的欧拉函数int Eular(int n){ //求解单独一个数字的欧拉函数值 int ans=n; for(int i = 2 ; i*i <= n ; i++) { if(n%i == 0) { n/=i; ans-=ans/i; while(n%i==0) { n/=i; } } } if(n>1) { ans-=ans/n; } return ans;}
//求出1到n范围内的所有数的欧拉函数void solve_Euler(){ memset(p,0,sizeof(p)); for(int i = 2 ; i <= 1000000 ; i++) { //利用筛选发求p[i] if(!p[i]) { for(int j = i ; j <= 1000000 ; j+=i) { if(!p[j]) { p[j]=j; } p[j]=p[j]/i*(i-1); } } }}int main(){ int n; solve_Euler(); //cout<<p[1]<<endl; while(scanf("%d",&n)!=EOF && n) { long long num=0; for(int i = 2 ; i <= n ; i++) { num+=p[i]; } printf("%I64d\n",num); } return 0;}
素数筛选法求1到n之间的素数
#include <iostream>#include <string>using namespace std;const int MAX=20000;bool prime[MAX];//prime[i]=1代表i是素数void Filterprime(){ memset(prime,true,sizeof(prime)); prime[0]=false; prime[1]=false; int i; for (i = 2;i*i <= MAX;i++) { if (prime[i]) { int j = i*2; while (j <= MAX) { prime[j]=false; j+=i; } } }}int main(){ Filterprime(); int n,count=1; while (cin>>n&&n>0) { if (prime[n] &&n!=2) { cout<<count++<<": yes"<<endl; } else cout<<count++<<": no"<<endl; }
扩展欧几里德算法是用来在已知a, b求解一组x,y使得a*x+b*y=Gcd(a,b)(解一定存在,根据数论中的相关定理)
#include <iostream>#include <cstdio>using namespace std;int ExGcd(int a,int b,int &x,int &y){ if(b==0) { x=1; y=0; return a; } int r=ExGcd(b,a%b,x,y); int t=x; x = y; y = t-a/b*y; return r;}int main(){ int a,b,x,y; while(scanf("%d%d",&a,&b)!=EOF) { ExGcd(a,b,x,y); printf("%d %d\n",x,y); } return 0;}
不定方程方程求解的问题 , 求a * x + b * y = n的整数解
1、先计算Gcd(a,b),若n不能被Gcd(a,b)整除,则方程无整数解;否则,在方程两边同时除以Gcd(a,b),得到新的不定方程a' * x + b' * y = n',此时Gcd(a',b')=1;
2、利用上面所说的欧几里德算法求出方程a' * x + b' * y = 1的一组整数解x0,y0,则n' * x0,n' * y0是方程a' * x + b' * y = n'的一组整数解(也是原方程的一组整数解);
3、根据数论中的相关定理,可得方程a' * x + b' * y = n'的所有整数解为:
x = n' * x0 + b' * t
y = n' * y0 - a' * t(t为整数)
上面的解也就是a * x + b * y = n 的全部整数解。
#include <iostream>using namespace std;__int64 t,p;__int64 euclid(__int64 a,__int64 b){if(b==0)return a;elsereturn euclid(b,a%b);}void extended_euclid(__int64 a,__int64 b){if(b==0){t=1;p=0;}else{__int64 temp;extended_euclid(b,a%b);temp=t-a/b*p;t=p;p=temp;}}int main(){__int64 x,y,n,m,L,gcd;cin>>x>>y>>m>>n>>L;if (m==n){cout<<"Impossible"<<endl;return 0;}__int64 a,b,c,c1;a=n-m;b=L;c=x-y; //由题意构建的a,b,c...a*x+b*y=c;gcd=euclid(a,b);c1=c%gcd;if (c1!=0){cout<<"Impossible"<<endl;return 0;}c/=gcd;a/=gcd;b/=gcd; extended_euclid(a,b);t*=c;p*=c;t=(t%b+b)%b;cout<<t<<endl;return 0;}
模线性方程ax=b (mod n) 求X的值。
该方程有解的充要条件为 gcd(a,n) | b ,即 b% gcd(a,n)==0.
当有解时,关键在于计算最大公约数 d=gcd(a,n) 与 最小解x0
引入欧几里得扩展方程 d=ax+by
注意:
计算n=2^k时,用位运算是最快的,1<<k (1左移k位)就是2^k
但是使用long long要注意格式, 1LL<<k
使用__int64要强制类型转换 (__int64)1<<k
#include <iostream>#include <cstdio>using namespace std;//d=ax+by,其中最大公约数d=gcd(a,n),x、y为方程系数,返回值为d、x、y__int64 EXTENDED_EUCLID(__int64 a,__int64 b,__int64& x,__int64& y){if(b==0){x=1;y=0;return a; //d=a,x=1,y=0,此时等式d=ax+by成立}__int64 d=EXTENDED_EUCLID(b,a%b,x,y);__int64 xt=x;x=y;y=xt-a/b*y; //系数x、y的取值是为满足等式d=ax+byreturn d;}int main(void){__int64 A,B,C,k;while(scanf("%I64d %I64d %I64d %I64d",&A,&B,&C,&k)){if(!A && !B && !C && !k)break;__int64 a=C;__int64 b=B-A;__int64 n=(__int64)1<<k; //2^k__int64 x,y;__int64 d=EXTENDED_EUCLID(a,n,x,y); //求a,n的最大公约数d=gcd(a,n)和方程d=ax+by的系数x、yif(b%d!=0) //方程 ax=b(mod n) 无解cout<<"FOREVER"<<endl;else{x=(x*(b/d))%n; //方程ax=b(mod n)的最小解x=(x%(n/d)+n/d)%(n/d); //方程ax=b(mod n)的最整数小解printf("%I64d\n",x);}}return 0;}
0 0
- 基础数论模版
- 数论模版
- 数论模版
- ##数论模版##
- ACM数论模版
- 数论小模版解题报告
- 数论基础
- 数论基础
- 数论 基础
- 数论基础
- 数论基础
- 数论基础
- 基础数论
- 基础数论
- 数论基础
- 数论基础
- 数论基础
- 数论基础
- 类练习题1:将浮点数转化为金额的类
- HttpClient使用详解
- 亚马逊是搜索领域最大竞争对手
- Hbase与Oracle比较(列式数据库与行式数据库)
- 3D游戏开发学习规划
- 基础数论模版
- 协方差的意义和计算公式
- 【LWJGL官方教程】Introduction 入门
- Problem E. Epic Win!
- Android控件之CheckBox多选框
- 两个ListView 嵌套数据出现错位,混淆的,图片闪烁问题
- android文件存储
- webSocket学习1
- JavaScript—————DOM