一、辗转相除法
(又称欧几里德算法):gcd(a, b) = gcd(b, a % b);
int gcd(int a, int b)
{
return b == 0 ? a : a % b;
}
另外:最小公倍数 * 最大公约数 == 两数之积
二、筛选法构造素数表
int visit[nMax];
int prime[nMax];
int getPrime(int n)//得到[1,n]中所有素数
{
int c;
memset(visit, 0, sizeof(visit));
int m = sqrt(n + 0.5);
for(int i = 2; i <= m; ++ i)
{
if(!visit[i])
{
prime[c ++] = i;
for(int j = i * i; j <= n; j += i)
visit[j] = 1;
}
}
for(int i = m + 1; i <= n; ++ i)
if(!visit[i])
prime[c ++] = i;
}
三、大整数取模
#include <cstdio>
#include <cstring>
int main()
{
const int nMax = 100;
char s[nMax];
int m;
scanf("%s %d", s, &m);
int len = strlen(s);
int ans = 0;
for(int i = 0; i < len; ++ i)
ans = (ans * 10 + s[i] - '0') % m;//如果前面超界,使用long long类型。
printf("%d\n", ans);
return 0;
}
四、欧拉函数值(小于n且与n互素的个数)
int euler_phi(int n)
{
int m = sqrt(n + 0.5);
int ans = n;
for(int i = 2; i <= m; ++ i)
if(n % i == 0)
{
ans = ans / i * (i - 1);
while(n % i == 0) n /= i;
}
if(n > 1) ans = ans / n * (n -1);//只能有一个因子 > m
}
五、Fib数列(矩阵实现)
![](https://img-my.csdn.net/uploads/201205/18/1337312102_9835.png)
//其中a[0]的值为fid(n+1)
void bsearch(int n)
{
if(1 == n)
{
a[0] = a[1] = a[2] = 1;
a[3] = 0;
return ;
}
bsearch(n>>1);
b[0] = a[0] * a[0] + a[1] * a[2];
b[1] = a[0] * a[1] + a[1] * a[3];
b[2] = a[2] * a[0] + a[3] * a[2];
b[3] = a[2] * a[1] + a[3] * a[3];
a[0] = b[0] % M;
a[1] = b[1] % M;
a[2] = b[2] % M;
a[3] = b[3] % M;
if(n & 1)//当n为奇数时
{
b[0] = a[0] + a[1];
b[1] = a[0];
b[2] = a[2] + a[3];
b[3] = a[2];
a[0] = b[0] % M;
a[1] = b[1] % M;
a[2] = b[2] % M;
a[3] = b[3] % M;
}
}
六、卡特兰数(Catalan)
h(n) = h(1) * h(n - 1) + h(2) * h (n -2 ) + ... + h(n - 2) * h(2) + h(n - 1) * h(1);(其中h(1) = h(2) = 1)
结论:h(n)=h(n-1)*(4*n-2)/(n+1);