发布于 

数论板子

旧文迁移

C的一些数论算法

来自洛谷博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#define MAXN 1010
using namespace std;
int c[MAXN][MAXN];
int pre_C(int n,int p)
{
c[0][0]=1;
for(int i=1;i<=n;i++)
{
c[i][0]=1;
for(int j=1;j<=i;j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%p;
}
return 1;
}
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return ans;
}
int lg[MAXN];
int pre_lg(int n)
{
for(int i=1;i<=n;i++)
lg[i]=lg[i-1]+((1<<lg[i-1])==i),printf("%d ",lg[i]-1);
}
int power(int a,int n,int p)
{
int ans=1,base=a;
while(n)
{
n&1?ans=(base*ans)%p:0;
base=(base*base)%p;
n>>1;
}
return ans;
}
int pr[MAXN<<4],cnt,i_pr[MAXN<<4];//is_prime
int pri(int n)
{
for(int i=2;i<=n;i++)
{
if(!i_pr[i])pr[cnt++]=i;
for(int j=0;j<=cnt&&pr[j]*i<=n;j++)
{
i_pr[i*pr[j]]=1;
if(i%pr[j]==0)break;
}
}
}
//欧拉函数:积性函数,表示小于i的所有与i 互质的数的个数
int ol(int n)
{
for(int i=1;i<=n;i++)
pr[i]=i;
for(int i=2;i<=n;i++)
{
if(pr[i]==i)
{
for(int int j=i;j<=n;j+=i)
pr[j]/=i*(i-1);
}

}
}
//费马小定理:a^(p-1)==1(mod p)->a^(-1)==a^(p-1)(mod p)
int power(int a,int n,int p)
{
int ans=1,base=a;
while(n)
{
n&1?ans=(base*ans)%p;
base=(base*base)%p;
n>>1;
}
return ans;
}
int fm(int n,int p)
{
return power(n,p-1,p);
}
//线性逆元推导:
/*
对于1->p的数i,其逆元 inv[i]可表示为
inv[i]==1/i(mod p)
取t=p/i,k=p%i
有 :
t*i+k==0(mod p)
=>-t*i==k(mod p)
同除以 k*i
=>-t*inv[k]==inv[i](mod p)
代回原式
=>inv[i]==-(p/i)*inv[p%i](mod p)
同余系下有
a(mod p)<==>(a%p+p)%p
=>inv[i]==(p-(p/i))*inv[p%i]%p
证毕

*/
//进制转换
/*
对于数m,在k进制下的表示
while(m)
{
a[++a[0]]=m%k;
m/=k;
if(ans[a[0]]<0)ans[cnt]-=r,t++;
}
*/
int inv[MAXN<<4]={0,1};
int find_inv(int n)
{
for(int i=2;i<=n;i++)
inv[i]=(p-p/i)*inv[i%p]%p;
return n;
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Zuni](http://example.com/) 创建,使用 Stellar 作为主题。