码迷,mamicode.com
首页 > 其他好文 > 详细

数学基础整理

时间:2017-12-10 14:28:39      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:数列   最大   result   公倍数   去掉   UI   mat   img   四十   

一些数论基本定理

( a + b ) mod c = ((a mod c) + (b mod c)) mod c

( a * b ) mod c = ((a mod c) * (b mod c)) mod c

 

消去律:若 gcd(c,p) = 1,则 ac ≡ bc mod p => a ≡ b mod p

消去律证明: ac ≡ bc mod p => ac = bc + kp => c(a-b) = kp

c和p没有除1以外的公因子 => 1) c能整除k 或 2) a = b 如果2不成立,则c|kp c和p没有公因子 => c|k,

所以k = ck‘ => c(a-b)=kp可以表示为c(a-b) =ck‘p 因此a-b = k‘p,得出a ≡ b mod p

 

快速幂

技术分享图片
int Pow
(int a,int b)
{
    //快速求a^b ,复杂度 log(b)
    if(b == 0)
        return 1;
    if(b & 1)   //b是奇数
    {
        return a * Pow(a,b-1);
    }
    else
    {
        int t = Pow
                (a,b/2);
        return t * t;
    }
}
快速幂1
技术分享图片
int Pow(int a,int b)
{
    //快速求a^b ,复杂度 log(b)
    int result = 1;
    int base = a;
    while(b)
    {
        if( b & 1)
            result *= base;
        base *= base;
        b >>= 1;
    }
    return result;
}
快速幂2

 

快速幂取模

 

技术分享图片
int PowMod(int a,int b,int c)
{
    //快速求 a^b % c ,要避免计算中间结果溢出
    int result = 1;
    int base = a%c;
    while(b)
    {
        if( b & 1)
            result = (result * base)%c;
        base = (base * base) % c;
        b >>= 1;
    }
    return result;
}
快速幂取模

 

 

等比数列二分求和取模

Sn= a+a2+...+an 要求 Sn mod p 如果用公式算,可能溢出,因此用二分法求

若 n是偶数

Sn= a+...+an/2 + an/2+1 + an/2+2 +...+ an/2+n/2 =(a+...+an/2) + an/2(a+...+an/2)

    =Sn/2+ an/2Sn/2 =(1+an/2)Sn/2

若n是奇数

Sn= a+...+a(n-1)/2 + a(n-1)/2+1 +... + a(n-1)/2+(n-1)/2 + a(n-1)/2+(n-1)/2 + 1

    =S(n-1)/2 + a(n-1)/2(a+...+a(n-1)/2)+an =(1+a(n-1)/2)S(n-1)/2+an

 

技术分享图片
int PowSumMod(int a,int n,int p)
{
    // return (a+ a^2 + ... + a^n) Mod p;
    if( n == 1)
        return a%p;
    if( n %2 == 0)
        return (1+PowMod(a,n/2,p))*PowSumMod(a,n/2,p) % p;
    else
        return ((1+PowMod(a,(n-1)/2,p)) * PowSumMod(a,(n-1)/2,p)+ PowMod(a,n,p)) % p;
}
等比数列二分求和取模

 

 

POJ3233 Matrix Power Series

矩阵快速幂+等比数列二分求和取模

给一个 n × n 的整数矩阵 A 和正整数k,m,

令 S = A + A 2 + A 3 + … + A k 求 S mod m

(S的每个都 mod m) n (n ≤ 30), k (k ≤ 109 ) and m (m < 104 )

 

技术分享图片
struct Matrix
{
    T a[32][32];
    int r; //行列数
    Mat(int rr):r(rr) { }
    void MakeI()   //变为单位矩阵
    {
        memset(a,0,sizeof(a));
        for(int i = 0; i < r; ++i)
            a[i][i] = 1;
    }
};
Matrix Pow(const Matrix & m,int k,int p)
{
    //求mk mod p
    int r = m.r;
    Matrix result(r);
    result.MakeI(); //MakeI是将result变为单位矩阵
    Matrix base = m;
    while(k)
    {
        if( k & 1)
            result = Product(result,base,p); //result*base mod p
        k >>= 1;
        base = Product(base,base,p);
    }
    return result;
}
矩阵快速幂+等比数列二分求和取模

 

 

欧几里得算法求最大公约数

 

技术分享图片
int Gcd(int a,int b)
{
    if( b == 0)
        return a;
    return Gcd(b,a%b);
}
gcd

 

最小公倍数:lcm(a,b) = a*b/gcd(a,b)

 

扩展欧几里得算法

ax+by=gcd(a,b)

有整数解(x,y) <=> bx+(a%b)y = gcd(a,b)

有整数解(x1,y1),且 x = y1, y = x1-[a/b]*y1

因此,可以在求gcd(a,b)的同时,对 ax+by=gcd(a,b)求解

技术分享图片
int GcdEx
(int a,int b,int &x ,int & y)
//求 ax+by=gcd(a,b)的整数解,返回gcd(a,b)
{
    if( b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int x1,y1;
    int gcd = GcdEx(b,a%b,x1,y1);
    x = y1;
    y = x1- a/b * y1;
    return gcd;
}
exgcd

ax+by=c 有解的充要条件是

gcd(a,b)|c • 设 d = gcd(a,b), k = c/d, ax+by = d的解是 (x1,y1)

则 ax+by = c的解集是: x = k*x1 + t*(b/d) y = k*y1 – t*(a/d) t为任意整数

 

扩展欧几里得算法求ax ≡ c(mod b)

求ax ≡ c(mod b)等价于求 ax+by = c 

设 d = gcd(a,b), k = c/d, ax+by = d的解是 (x1,y1)

则ax≡c(mod b) 的解集是: x = k*x1 + t*(b/d) t为任意整数 其中模b不同的解共有 d 个,为: x = k*x1 + t*(b/d) t=0,1,..d-1

求ax ≡ c(mod b) 的最小非负整数解: 令 ans = k * x1; s = b/d; 则 x = ans + t*s t为任意整数

则最小非负整数解是:(ans%s + s)%s

 

中国剩余定理

 

 

孙子定理,韩信点兵,隔墙算,鬼谷算,大衍求一术...

"物不知数"问题:"今有物不知其数,三三数之剩二,五 五数之剩三,七七数之剩二,问物几何?答曰:‘二十三.‘ 术曰:三三数之剩二,置一百四十,五五数之剩三,置六 十三,七七数之剩二,置三十,并之,得二百三十三,以二 百一十减之,即得.凡三三数之剩一,则置七十,五五数 之剩一,则置二十一,七七数之剩一,则置十五,即得." --孙子算经

设n组数(ai, bi), 其中bi两两互素

求x使得 x = a1 mod b1 x = a2 mod b2 ... x = an mod bn

给定两两互质的正整数n1,n2,...,nk,要求找到最小的正整 数x,满足方程组x≡ai(mod ni) (i=1,2...k)

算法步骤: 令n=n1n2...nk, mi=n/ni 

显然gcd(mi,ni)=1,

利用扩展欧几里德算法计算出xi满 足mixi≡1(mod ni)

x = (a1x1m1+a2x2m2+...+akxkmk) mod n 

此方程组任意两个解模 n 同余,因此x就是最小的

此方程组任意两个解模 n 同余 证:设有两个解 x1,x0 则: x1 ≡ ai (mod ni) (i=1,2...k) x0 ≡ ai (mod ni) (i=1,2...k) => ni|(x1-x0) (i=1,2...k) ni|(x1-x0) 且ni两两互质 => n|(x1-x0) => x1 ≡ x0 (mod n)

中国剩余定理的一般情况

给定正整数n1,n2,...,nk(未必两两互质),要求找到x,

满 足x≡ai(mod ni) (i=1,2...k)

x ≡ a1( mod n1)

x ≡ a2( mod n2)

=> x + u*n1 = a1 且 x - v*n2 = a2

=> n1*u + n2*v = (a1-a2) 此关于u,v的方程,当且仅当 gcd(n1,n2)|(a1-a2)时有解

设用扩展欧几里得算法求得 n1*u + n2*v = (a1-a2) 根为 (u0,v0)则:

则此方程解集为: u = u0 + t*(n2/gcd(n1,n2)) v = v0 – t*(n1/gcd(n1,n2)) t为任意整数

x + u*n1 = a1 => x的解集为:a1 – u0n1 – tn1n2/gcd(n1,n2) 即:x = a1 – u0n1 – t*lcm(n1,n2) t为任意整数

x = a1 – u0n1 – t*lcm(n1,n2) t为任意整数

等价于将

x ≡ a1( mod n1)

x ≡ a2( mod n2)

合并为: x ≡ a1 – u0n1 (mod lcm(n1,n2)) 再继续两个方程并为一个,最后就能求得x的解空间

 

线性筛法求素数

朴素筛法求n以内的所有质数

初始时容器内为2到n的所有数

取出最小的数p,p一定是质数,删去除p外的所有p的倍数

重复上述步骤直到向后找不到没被删掉的数

缺陷:一个数可能被重复删去多次,影响效率

改进: 对每个素数p 考虑所有i,

若i的最小素因子>=p,

则将 i*p去掉 i = q1 *q2 *...qn qi是素数,

q1 >= p i*p = p*q1 *q2 *...qn i*p只会被删掉一次,只在考察p的时候被删,不会在考察q1 q2 qn 的时候被删

技术分享图片
int main()
{
    int n;
    cin >> n; //求n以内素数
    vector<int> prime;
    vector<bool> isPrime(n+1);
    for(int i = 1; i <= n; ++i)
        isPrime[i] = true;
    for(int i = 2; i <= n; ++i)
    {
        if( isPrime[i]) //处理到i时它还没被删掉,则i为素数
            prime.push_back(i);
        for(int j = 0; j < prime.size() ; ++j)
        {
            if( i*prime[j] <= n)
                isPrime[i*prime[j]] = false;
            else break;
            if( i % prime[j] == 0)// prime[j]是i的最小素因子
                break;
        }
    }
    for(int i = 0; i < prime.size(); ++i)
        cout << prime[i] << endl;
    return 0;
}
线性筛

 

数学基础整理

标签:数列   最大   result   公倍数   去掉   UI   mat   img   四十   

原文地址:http://www.cnblogs.com/oi-forever/p/8016670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!