您的位置:首页 > 其它

关于数论的一些总结

2017-07-29 23:58 2141 查看
结论:我数论太渣了……

言归正传……先列出几个常用的性质/结论

同余式:

1. da≡db (mod m) 则a≡b (mod m/(m,d) ) (这在取遍剩余系会用到)

2. a≡b (mod m) m'|m , a≡b (mod m')

3. a≡b (mod mi) i=1..k 等价于 a≡b (mod M) M=[m1,m2,..mk]

一般剩余系:

剩余系就是可能余数组成的集合,简化剩余系也称既约剩余系,是模n的完全剩余系的一个子集,其中每个元素与n互素。

1. 模p的剩余系{rk},若(p,d)=1那么{d*rk}也是模p的剩余系

这个很重要,如果求ax mod p的既约剩余系的大小,我们只要利用同余式的性质1

转化为x*a/gcd(a,p) mod (p/gcd(a,p)),根据这个理论 x取值个数就是p/gcd(a,p)

2. 设模m1的既约剩余系为R1,m2的既约剩余系为R2,m1m2互质,则模m1m2的既约剩余系为R={x=m2x1+m1x2 (mod m1m2) | x1∈R1,x2∈R2}

这个结论证明可以考虑任意两个x互不同余即可(作差判断)

这就告诉我们一个很厉害的东西 S(M)表示M既约剩余系的大小的话,S(M)=S(m1)*S(m2)

3. 这个结论推广到k维就是,设模mk的既约剩余系为Rk, mk两两互质,M=∏mi 则模M的既约剩余系为R={ ∑M*mi-1*ai (mod M) | xi∈Ri }

因此以后我们求模M的剩余系大小,可以对M质因数分解分别求出后再相乘

阶、原根、指标:

阶(又叫指数):a,m为互素整数且m>=2 ,则使 ar≡1(mod m) 成立的最小正整数 r 记为 a 模 m 的指数,记作ord_m(a)

根据欧拉定理,显然ord_m(a)一定是φ(m)的约数

阶有几个性质: 1. ord_m(a)=xy 则 ord_m(ax)=y 2.ord_m(a)=x, ord_m(b)=y (x,y)=1 则ord_m(ab)=xy;

3. ord_m(a)=t ord_m(ax)=t/gcd(t,x) (其实就是性质1的变形)

原根:阶中要求(a,m)互素,所以a^x与m互素,所以ax模m的余数与m互素,这样这个余数只可能有 φ(m) 种不同的取值。

(这里我想到了了一个很有意思的结论:1~n内与n互质的数的和为{n*φ(n)+[n==1]} /2

这里考虑gcd(i,n)=1,则gcd(n,n-i)=1,证明用反证法即可。)

当满足ord_m(a)=φ(m)的a称作模m的原根,记作g。

这有一个显然的结论若 x=0,1,2,3,...,φ(m)-1,则 gx 模 m 的余数都和 m 互素,并且模 m 两两不同余。

指标:简单来说,就是一切小于m且与m互质的数r,都存在唯一个数k(k<φ(m)),使得gk≡r (mod m)

我们就把k叫作r的指标,记作I(r)

这是一个非常有用的性质,之后的题目我们会经常看到他。

指标有这么几个性质:1. I(ab)≡I(a)+I(b) (mod m) 2. I(ak)≡kI(a) (mod m)

简而言之,指标就像是数论里的取对数。

原根和求指标将在后面的同余方程中起到巨大作用,但是首先我们要知道什么数有原根

直接上结论: 当且仅当m=2,4,pk,2pk时才有原根,p是某一奇素数

证明可以看《初等数论及其应用》

还有一个非常有用的定理是:若g是某一奇素数p的原根,那么g也是pk的原根,证明依然在《初等数论及其应用》

事实上,一个数p的原根的数目为φ(φ(p)) (考虑若g是p的原根,gu是p的原根当且仅当gcd(u,φ(p))=1)

另外我们注意到2的原根是1,4的原根是3,但其他2次幂是没有原根的(在高次剩余里,模2次幂会带来不小的麻烦)

事实上有一个恒等式:aφ(xy)/2≡1 (mod xy) (x,y互素且a与xy互素)

在2次幂的时候就有a^(2k)≡1 (mod 2k+2) 恒成立,所以2的3次及以上次幂没有原根

(补充一个很有意思的结论:5模2k+2的指数正好是2k )

一个数的原根不止一个,一般就找最小的那个就可以了

其他的原根可用最小原根的gu表示(gu是p的原根当且仅当gcd(u,φ(p))=1)

找m的最小原根一般就是暴力枚举g,然后穷举m的每个质因数p,判断gφ(m)/p≡1 (mod m)是否成立(成立的话就不是原根)

一道找所有原根的题目

1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<cmath>
6 #include<map>
7
8 using namespace std;
9 typedef long long ll;
10 int A,p,B;
11 map<int,int> mp;
12
13 int gcd(int a,int b)
14 {
15     return (b==0)?a:gcd(b,a%b);
16 }
17
18 ll quick(ll x,int y,int mo)
19 {
20     ll s=1;
21     while (y)
22     {
23         if (y&1) s=s*x%mo;
24         x=x*x%mo;
25         y>>=1;
26     }
27     return s;
28 }
29
30 void exgcd(int a, int b, int &x, int &y)
31 {
32      if (!b){x=1; y=0; return;}
33      else {
34           exgcd(b,a%b,x,y);
35           int xx=x, yy=y;
36           x=yy; y=xx-a/b*yy;
37      }
38 }
39
40 int inv(int a,int p)
41 {
42     int g=gcd(a,p);
43     if (g!=1) return -1;
44     a/=g; int w=p/g,x,k;
45     exgcd(a,w,x,k); x=(x+w)%w;
46     return x;
47 }
48
49 int bsgs(int y,int z,int p)
50 {
51     y%=p;
52     mp.clear();
53     mp[1]=p-1;
54     ll m=(int)sqrt(p)+1, now=1;
55     for (int i=1; i<=m; i++)
56     {
57         now=now*(ll)y%p;
58         if (!mp[now]) mp[now]=i;
59     }
60     int x=inv(now,p);
61     if (x==-1) return -1;
62     ll step=z;
63     for (int i=0; i<m; i++)
64     {
65         if (mp[step])
66         {
67            if (step==1) mp[step]=0;
68            return mp[step]+i*m;
69         }
70         step=1ll*step*x%p;
71     }
72     return -1;
73 }
74
75 int ext(int a,int b,int p)
76 {
77     if (b==1) return 0;
78     ll t=gcd(a,p),d=1,k=0;
79     while (t!=1)
80     {
81         if (b%t) return -1;
82         ++k,b/=t,p/=t, d=d*(a/t)%p;
83         if (b==d) return k;
84         t=gcd(a,p);
85     }
86     b=1ll*b*inv(d,p)%p;
87     int s=bsgs(a,b,p);
88     if (s==-1) return -1;
89     else return s+k;
90 }
91
92 int main()
93 {
94     while (scanf("%d%d%d",&A,&p,&B)!=EOF)
95     {
96         if (!A&&!p&&!B) break;
97         int ans=ext(A,B,p);
98         if (ans==-1) puts("No Solution");
99         else printf("%d\n",ans);
100     }
101 }


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