ACM——简单数论
辗转相除求最大公约数(欧几里得算法)
int gcd(int a,int b){
if(a%b==0)return b;
else return gcd(b,a%b);
}
int gcd(int a,int b){
if(b==0)return a;
else return gcd(b,a%b);
}
求线性方程组
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
int ed_gcd(int a,int b,int &x,int &y){
if(b==0){
x=1;y=0;
return a;
}
int ans=ed_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
求乘法逆元
什么是乘法逆元?
如果a*x=1(mod m)
这里我们称x是a关于m的乘法逆元对于正整数b
bool is_prime(int n){
if(n<2)return false;
for(int i=2;i*i<=n;i++){
if(n%i==0)return false;
}
return true;
}
//埃氏筛法
int prime[N];
bool is_prime[N];
//返回素数的个数
int sieve(int n){
for(int i=0;i<=n;i++)is_prime[i]=true;
int p=0;
is_prime[0]=false;
is_prime[1]=false;
for(int i=2;i<=n;i++){
if(is_prime[i]){
prime[p++]=i;
for(int j=i*2;j<=n;j+=i){
is_prime[j]=false;
}
}
}
return p;
}
巴什博弈
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。
显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。