数论入门基础
數論基礎
- 一.輾轉相除求最大公約數
- 二.擴展歐幾里得算法
- 1.求解x,y滿足ax+by=c
- 2.求逆元
- 3.求同余式的解
- 三.素數
- 1.基礎算法(素性測試,約數枚舉,整數分解)
- 2.素數篩
- 四.快速冪取模
- 五.歐拉函數
一.輾轉相除求最大公約數
a/b=p…q(q=a%b) -> a=b*p+q -> gcd(a,b)=gcd(b,q)
可持續遞歸下去直到后面的數為0
時間復雜度:**O(log max(a,b)),**底數為2.
若b>a:gcd(a,b)=gcd(b,a%b)=gcd(b,a);(一次變化為下述情況)。
若a>b:
(1)b>a/2,gcd(a,b)=gcd(b,a%b),a%b=a-b<a/2;
(2)b<a/2,gcd(a,b)=gcd(b,a%b),a%b<b<a/2;
綜上,a每次都縮小1/2以上,故時間復雜度為O(log max(a,b))。
補充:lcm(a,b)(最小公倍數)=a*b/gcd(a,b)
二.擴展歐幾里得算法
1.求解x,y滿足ax+by=c
裴蜀定理(或貝祖定理):若a,b是整數,且gcd(a,b)=d,那么對于任意的整數x,y,ax+by都一定是d的倍數,特別地,一定存在整數x,y,使ax+by=d成立。
重要推論:a,b互質的充分必要條件是存在整數x,y使ax+by=1.
n個整數間的裴蜀定理:設a1,a2,a3…an為n個整數,d是它們的最大公約數,那么存在整數x1…xn使得x1a1+x2a2+…xnan=d。
特別來說,如果a1…an存在任意兩個數是互質的(不必滿足兩兩互質),那么 存在整數x1… xn使得x1a1+x2a2+ …xnan=1。證法類似兩個數的情況。
求得一組x,y后,可通過: (k為任意整數)
x’=x+(b/gcd)k
y’=y-(a/gcd)k
求得全部解。
在此基礎上求解ax+by=c(c一定為gcd的整數倍)的全部解
x’=x(c/gcd)+(b/gcd)k
y’=y(c/gcd)-(a/gcd)k
注意:在ax+by=gcd的全部解的基礎上都乘以 c/gcd會漏解。
2.求逆元
時間復雜度:O(logn),適用于mod很大,計算個數不多。
//求逆元 int extgcd(int a,int b,int &x,int &y) {int res=a;if(b!=0){res=extgcd(b,a%b,y,x);y-=(a/b)*x;}else x=1,y=0;return res; } ll getan(ll a) {ll x,y;ll s=extgcd(a,mod,x,y);return s==1?(x%mod+mod)%mod:-1; }3.求同余式的解
同余定理:給定一個正整數m,如果兩個整數a和b滿足(a-b)能夠被m整除即(a-b)/ m得到一個整數,那么就稱整數a與b對模m同余,記作 a≡b(mod m)。(就相當于a%m=b%m)
消去律:若 gcd(c,p) = 1,則 ac ≡ bc mod p => a ≡ b mod p
反身性:a≡a (mod m)
對稱性: 若a≡b(mod m),則b≡a(mod m)
傳遞性: 若a≡b(mod m),b≡c(mod m),則a≡c(mod m)
同余式相加減:若a≡b(mod m),b≡c(mod m),則a ± c≡b ± d(mod m)
同余式相乘:若a≡b(mod m),b≡c(mod m),則ac≡bd(mod m)
除法:若ac ≡ bc (mod m) c≠0 則 a≡ b (mod m/gcd(c,m)) 其中gcd(c,m)表示c,m的最大公約數。特殊地 ,gcd(c,m)=1 則a ≡ b (mod m)
冪運算:
如果a ≡ b (mod m),那么a^n ≡ b^n (mod m)
若a ≡ b (mod m),n|m,則 a ≡ b (mod n)
若a ≡ b (mod mi) (i=1,2…n) 則 a ≡ b (mod [m1,m2,…mn]) 其中[m1,m2,…mn]表示m1,m2,…mn的最小公倍數
a x ≡ c (mod m)—>(ax-c)%m=0
則存在 ax-c=my,令y=-y -->c=ax+my會到上述問題1
三.素數
1.基礎算法(素性測試,約數枚舉,整數分解)
//時間復雜度均為O(log(x))//素性測試 bool isprime(int x) {if(x<=1)return false;for(int i=2;i*i<=x;i++){if(x%i==0)return false;}return true; }//約數枚舉 void getyueshu(int x) {vector<int>a;for(int i=1;i*i<=x;i++){if(x%i==0){a.push_back(i);if(x/i!=i)a.push_back(x/i);}}for(int i=0;i<a.size();i++)cout<<a[i]<<" ";cout<<"\n"; }//整數分解 void getnum(int x) {vector<int>a;for(int i=2;i*i<=x;i++){while(x%i==0){a.push_back(i);x=x/i;}if(x==1)break;}if(x!=1)a.push_back(x);for(int i=0;i<a.size();i++)cout<<a[i]<<" ";cout<<"\n"; }2.素數篩
//時間復雜度O(n*loglogn) int prime[1000010]; bool isprime[1000010]; int sieve(int n) {int cnt=0;for(int i=0;i<=n;i++)isprime[i]=true;for(int i=2;i<=n;i++){if(isprime[i]){prime[cnt++]=i;for(int j=i*2;j<=n;j+=i)isprime[j]=false;}}return cnt; }//時間復雜度O(n) int prime[1000010]; bool isprime[1000010]; int sieve(int n) {memset(isprime,true,sizeof(isprime));int cnt=0;for(int i=2;i<=n;i++){if(isprime[i])prime[cnt++]=i;for(int j=0;j<cnt&&prime[j]*i<=n;j++){isprime[prime[j]*i]=false;if(i%prime[j]==0)break;}}return cnt; }//區間篩法 bool isprime1[1000010]; bool isprime2[1000010]; int sieve(ll a,ll b) {memset(isprime1,true,sizeof(isprime1));memset(isprime2,true,sizeof(isprime2));int cnt=0;for(ll i=2;i*i<b;i++){if(isprime1[i]){for(ll j=2*i;j*j<b;j+=i)isprime1[j]=false;for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i)isprime2[j]=false;}}for(int i=2;i<b-a;i++)if(isprime2[i])cnt++;return cnt; }四.快速冪取模
//時間復雜度O(log n) ll modpow(ll x,ll n,ll mod) {ll res=1;while(n>0){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res; }//時間復雜度O(log n) ll modpow(ll x,ll n,ll mod) {if(n==0)return 1;ll res=modpow(x*x%mod,n/2,mod);if(n&1)res=res*x%mod;return res; }五.歐拉函數
歐拉函數:就是對于一個正整數n,小于n且和n互質的正整數(包括1)的個數,記作φ(n) 。
歐拉函數的通式:φ(n)=n(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)……(1-1/pn)
其中p1, p2……pn為n的所有質因數,n是不為0的整數。φ(1)=1(唯一和1互質的數就是1本身)。
歐拉函數為積性函數,即:若m,n互質, φ ( m n ) = φ ( m ) ? φ ( n ) 。
總結
- 上一篇: [OpenDrive] OpenDriv
- 下一篇: Eclipse安装中文简体语言包(详细)