您的位置:首页 > 其它

数论模板

2017-08-12 20:53 183 查看


欧几里德算法(辗转相除法)

int gcd(int a, int b)
{
return b ==  0 ? a : gcd(b, a%b);
}
1
2
3
4
1
2
3
4


唯一分解定理

int judge(int *x)
{
x[2] /= gec(x[2],x[1]);
for(int i = 2; i <= k; i ++)
x[2] /= gcd(x[i],x[2]);
}
1
2
3
4
5
6
1
2
3
4
5
6


扩展欧几里德

void gcd(int a, int b, int &d, int &x, int &y)
{
if(!b)
{
d = a;
x = 1;
y = 0;
}
else
{
gcd(b, a%b, y, x);
y -= x * (a/b);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14


Eratosthenes筛法

void eratosthenes()
{
inty m = sqrt(n + 0.5)
memset(vis,0,sizeof(vis));
for(int i = 2; i <= m; i ++)
if(!vis[i])
for(int j = i*i; j <= n; j += i)
vis[j] = i;

}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10


模算术公式

(a+b)modn=((amodn)+(bmodn))modn 
(a−b)modn=((amodn)−(bmodn)+n)modn 
abmodn=(amodn)(bmodn)modn

int mul_mod(int a, int b, int n)
{
a %= n;
b %= n;
return (int)((long long )a * b % n);
}
1
2
3
4
5
6
1
2
3
4
5
6


大整数取模

int main()
{
char n[MAXN];
int m;
scanf("%d", n, &m);
int len = strlen(n);
int sns = 0;
for(int i = 0; i < len; i ++)
ans = (int )(((long long)ans*10 +n[i]- '0')%m);
printf("%d\n");
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12


幂取模(快速幂)

int pow_mod(int a, int n, int m)
{
int ans = 1;
for(int i = 0; i < n; i ++)
ans = (int)((long long)ans * a % m);
}
1
2
3
4
5
6
7
1
2
3
4
5
6
7


幂取模(递归写法)

int pow_mod(int a, int n, int  m)
{
if(n == 0)
return 1;
int x = pow_mod(a, n/2, m);
long long ans = (long long )x * x % m;
if(n%2 == 1)
ans = ans *a % m;
return (int )ans;
}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10


快速幂(非递归)

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p
LL ret = 1;
while(b){
if(b & 1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
return ret;
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9


快乘

LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p
LL ret = 0;
while(b){
if(b & 1) ret = (ret + a) % p;
a = (a << 1) % p;
b >>= 1;
}
return ret;
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9


欧拉函数

int euler(int x)
{
int i, res = x;
for (i = 2;i < (int)sqrt(x * 1.0) + 1; i++)
if(x % i == 0)
{
res = res / i * (i - 1);
while(x % i == 0)
x /= i; // 保证 i 一定是素数
}
if(x > 1)
res = res / x * (x - 1);
return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14


中国剩余定理

//n个方程:x=a[i](mod m[i]) (0<=i<n)
LL china(int n, LL *a, LL *m){
LL M = 1, ret = 0;
for(int i = 0; i < n; i ++) M *= m[i];
for(int i = 0; i < n; i ++){
LL w = M / m[i];
ret = (ret + w * inv(w, m[i]) * a[i]) % M;
}
return (ret + M) % M;
}
1
2
3
4
5
6
7
8
9
10


1
2
3
4
5
6
7
8
9
10

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: