zoukankan      html  css  js  c++  java
  • 数论定理篇

    真是的,博主本来就菜,又懒得刷题。

    只好一边划水,一边从别人的博客上搬代码。

    1)素数筛法

    2)快速幂,快速乘

    快速乘(注意:变乘法为加法):

    LL Kmul(LL a, LL b, LL mo){ //计算a*b%mo 
        LL ret = 0;
        while(b){
            if(b & 1) ret = (ret + a) % mo;
            a = (a+a) % mo;
            b >>= 1;
        }
        return ret;
    }

        //即每次a乘2,b除2

    3)欧几里得求gcd,lcm

    递归,gcd(a,b)= gcd(b,a%b) = gcd(x,0) = x

      lcm(a,b)=  a*b/gcd(a,b) = a/gcd(a,b)*b

    4)扩展欧几里得

      解决ax+by=c整数解问题

    5)费马-欧拉定理

      I、欧拉定理

        若n、a互质,a^φ(n) ≡ 1 (mod n)    //同余式

      II、费马小定理

        若p、a互质,并且p是质数,a^(p-1) ≡1(mod p)

     

      //循环节

    6)逆元inv(解决在除法过程中取模问题)

      定义:a*inv(a) ≡ 1 (mod m) 

      根据费马小定理,若m为质数,inv(a)=a^(m-2)   //m尽量取大

              若不是,转换为扩展欧几里得问题

      O(n)求出2->N的逆元(MOD要为质数)

      

    int init(){
        inv[1] = 1;
        for(int i = 2; i < N; i ++){
            inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
        }
    }
    

      

    7)欧拉函数φ(n)或phi(n)

      phi(n)为1-n中与n互质的数的个数

      模仿素数埃筛

      

    int phi[N];
    void Euler(){
        phi[1] = 1;
        for(int i = 2; i < N; i ++){
            if(!phi[i]){
                for(int j = i; j < N; j += i){
                    if(!phi[j]) phi[j] = j;
                    phi[j] = phi[j] / i * (i-1);
                }
            }
        }
    }
    

     

    8)中国剩余定理

    求一个x,模m1余r1,模m2余r2,......

    若m1,m2....两两互质,则x有解。

    模板代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long LL;
     5 typedef pair<LL, LL> PLL;
     6 LL a[100000], b[100000], m[100000];
     7 LL gcd(LL a, LL b){
     8     return b  ? gcd(b, a%b) : a;
     9 }
    10 void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    11     if (!b) {d = a, x = 1, y = 0;}
    12     else{
    13         ex_gcd(b, a % b, y, x, d);
    14         y -= x * (a / b);
    15     }
    16 }
    17 LL inv(LL t, LL p){
    18     LL d, x, y;
    19     ex_gcd(t, p, x, y, d);
    20     return d == 1  ? (x % p + p) % p : -1;
    21 }
    22 PLL linear(LL A[], LL B[], LL M[], int n) { 
    23     LL x = 0, m = 1;
    24     for(int i = 0; i < n; i ++) {
    25         LL a = A[i] * m, b = B[i] - A[i]*x, d = gcd(M[i], a);
    26         if(b % d != 0)  return PLL(0, -1); 
    27         LL t = b/d * inv(a/d, M[i]/d)%(M[i]/d);
    28         x = x + m*t;
    29         m *= M[i]/d;
    30     }
    31     x = (x % m + m ) % m;
    32     return PLL(x, m);
    33 }
    34 int main(){
    35     int n;
    36     while(scanf("%d", &n) != EOF){
    37         for(int i = 0; i < n; i ++){
    38             a[i] = 1;
    39             scanf("%d%d", &m[i], &b[i]);  //分别为m,r
    40         }
    41         PLL ans = linear(a, b, m, n);
    42         if(ans.second == -1) printf("-1
    ");
    43         else printf("%lld
    ", ans.first);
    44     }
    45 }
    View Code

    9)大组合数,卢卡斯定理(p为质数)

      C(n, m) % p  =  C(n / p, m / p) * C(n%p, m%p) % p     //递归

    10)说到组合,斯特林数,卡特兰数  //数列工具OEIS

      第二类斯特林数:将有n个元素的集合划分成m个集合(没有空集合),有多少种划分,递推式:

      

       另斯特林公式近似求n!:

      

      求n!的位数:   //  (int)lg(n!) + 1 

      

     

      卡特兰数://出栈序列

        其前几项为 : 1, 1, 2, 5, 14, 42, 132, 429,

     

      

        若n次入栈,m次出栈:C(n+m,n)-C(n+m,m-1)

     

  • 相关阅读:
    java.lang.AbstractMethodError: com.microsoft.jdbc.base.BaseDatabaseMetaData.supportsGetGeneratedKeys()Z
    安装oracle后java -version命令显示 jdk version "1.3.1"的原因
    jquery 获取和设置Select选项常用方法总结
    select动态增加option
    Jquery detect page refresh
    HibernateTemplate 查询
    The dialect was not set. Set the property hibernate.dialect
    hibernate的异常 Session was already closed
    <c:forEach>取得集合数量
    Jstl标签<c:forEach>的用法
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/8418221.html
Copyright © 2011-2022 走看看