數論 +幾何(檢修中

來讓我們看看大佬是怎麼寫的  注:這個dalao是真牛逼  數論很多東西都能用

《什麼是數學》《怎樣解題》

在講述這節知識前我們先引入一些知識方便使用

以後出現(mod p)就表示這個公式是在求餘p的條件下成立

1   12≡ 5( mod 7 )表示在餘7的情況下12和5是一樣的

     a ≡ b( mod c )    m ≡ n( mod c )  那麼a + m ≡ b + n( mod c )

     ( a - b ) % c = [ (a % c - b % c ) + c ]%c

     ( a +  b) %c = (a%c +  b%c) %c

幺元  在一份封閉的運算系統內  設其爲e  若e*a=a   a*e=a    那麼e就是這個運算系統內的幺元 (類似於單位元 單位向量

逆元   若 a*b=1  那麼a和b互爲逆元

         如果  a*x = 1  那麼x是a的倒數,x = 1/a  但是a如果不是1,那麼x就是小數  那數論中,大部分情況都有求餘,所以現在問題變了       a*x  = 1 (mod p)  那麼x一定等於1/a嗎   不一定   所以這時候,我們就把x看成a的倒數,只不過加了一個求餘條件,所以x叫做    a關於p的逆元

        比如2 * 3 % 5 = 1,那麼3就是2關於5的逆元,或者說2和3關於5互爲逆元    這裏3的效果是不是跟1/2的效果一樣,所以才叫數論倒數

         a的逆元,我們用inv(a)來表示

             那麼(a  /  b) % p = (a * inv(b) ) % p = (a % p * inv(b) % p) % p

判斷一個數能不能被3整除把它各個位上的數相加餘3

費馬小定理   

a^(p-1) ≡1 (mod p)       a^(p-2) ≡ inv(a) (mod p)     所以inv(a) = a^(p-2) (mod p)  a和p互素

EXgcd(拓展歐幾里得)

   ax+by=gcd(a,b)   貝祖等式

 a,b不全爲0 

ax1+by1=bx2+(a-a/b*b)y2

x1=y2;

y1=x2-(a/b)y2;

   拓展歐幾里得求出來的最小逆元大概率是負數

 

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;
}
LL Fermat(LL a, LL p){//費馬求a關於b的逆元 
        return pow_mod(a, p-2, p);
}

 

#include<cstdio>
typedef long long LL;
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    if (!b) {d = a, x = 1, y = 0;}
    else{
        ex_gcd(b, a % b, y, x, d);
        y -= x * (a / b);
    }
}
LL inv(LL t, LL p){//如果不存在,返回-1 
    LL d, x, y;
    ex_gcd(t, p, x, y, d);
    return d == 1 ? (x % p + p) % p : -1;
}
int main(){
    LL a, p;
    while(~scanf("%lld%lld", &a, &p)){
        printf("%lld\n", inv(a, p));
    }
}

看看dalao怎麼推的

中國剩餘定理給出了以下的一元線性同餘方程組:

中國剩餘定理1

 

中國剩餘定理說明:假設整數m1,m2, ... ,mn兩兩互質,則對任意的整數:a1,a2, ... ,an,

 方程組(S)

有解,並且通解可以用如下方式構造得到:

 中國剩餘定理2

是整數m1,m2, ... ,mn的乘積,並設

 中國剩餘定理3

是除了mi以外的n- 1個整數的乘積。

 中國剩餘定理4

這個就是逆元了

 中國剩餘定理5 

通解形式爲

 中國剩餘定理6 

在模M的意義下,方程組(S)只有一個解:

 中國剩餘定理7

//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;
}

 

 若 m1,m2, ... ,mn兩兩不保證互質

     

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
PLL linear(LL A[], LL B[], LL M[], int n) {//求解A[i]x = B[i] (mod M[i]),總共n個線性方程組 
    LL x = 0, m = 1;
    for(int i = 0; i < n; i ++) {
        LL a = A[i] * m, b = B[i] - A[i]*x, d = gcd(M[i], a);
        if(b % d != 0)  return PLL(0, -1);//答案不存在,返回-1 
        LL t = b/d * inv(a/d, M[i]/d)%(M[i]/d);
        x = x + m*t;
        m *= M[i]/d;
    }
    x = (x % m + m ) % m;
    return PLL(x, m);//返回的x就是答案,m是最後的lcm值 
}

排列組合

C_{n}^{m}=C_{n-1}^{m}+C_{n-1}^{m-1}

歐拉函數(暫時不會)

簡單概括一下就是求每個數和比他小的數有多少個與他互質(含1)

void eulor()
{
	int cnt = 0;
	for (i = 2; i < maxn; i++)
	{
		if (isprime[i] == 0)
		{
			prime[cnt++] = i;
			phi[i] = i - 1;
		}
		for (j = 0; j < cnt && i * prime[j] < maxn; j++)
		{
			isprime[i * prime[j]] = 1;
			if (i % prime[j] == 0)
				phi[i * prime[j]] = phi[i] * prime[j];
			else
			{
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			}
		}
	}
}

幾何 

判斷一個點在直線哪一側

(xp,yp)的點P

設直線是由其上兩點(x1,y1),(x2,y2)確定的,直線方向是由(x1,y1)到(x2,y2)的方向。

假設直線方程爲:Ax+By+C=0,則有:

    A=y2-y1;   B=x1-x2;  C=x2*y1-x1*y2;               D=A*xp+B*yp+C;

若D<0,則點P在直線的左側;若D>0,則點P在直線的右側;若D=0,則點P在直線上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章