zoukankan      html  css  js  c++  java
  • [数论专题]

    一:素数

     1 int prime[N],p[N],tot;
     2 void init()
     3 {
     4     for(int i=2;i<N;i++)    prime[i]=1;
     5     for(int i=2;i<N;i++)
     6     {
     7         if(prime[i]==1) p[++tot]=i;
     8         for(int j=1;j<=tot;j++)
     9         {
    10             prime[i*p[j]]=0;
    11             if(i%p[j]==0)   break;
    12         }
    13     }
    14 }
    View Code

    二:快速幂

    1 LL pow_mod(LL a, LL b, LL p){//a的b次方求余p
    2     LL ret = 1;
    3     while(b){
    4         if(b & 1) ret = (ret * a) % p;
    5         a = (a * a) % p;
    6         b >>= 1;
    7     }
    8     return ret;
    9 }
    View Code

    快速乘

    1 LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p
    2     LL ret = 0;
    3     while(b){
    4         if(b & 1) ret = (ret + a) % p;
    5         a = (a + a) % p;
    6         b >>= 1;
    7     }
    8     return ret;
    9 }
    View Code

    三:gcd和lcm

    lcm=a/gcd*b;

    1 LL gcd(LL a, LL b){
    2     if(b == 0) return a;
    3     else return gcd(b, a%b);
    4 }
    5 
    6 LL gcd(LL a, LL b){
    7     return b ? gcd(b, a%b) : a;
    8 }
    9 //两种都可以
    gcd

    gcd(ka, kb) = k * gcd(a, b)

    lcm(ka, kb) = k * lcm(a, b)

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

    四:扩展欧几里得算法

    已知 a,b 求 一组解 x,y 满足 ax+by = gcd(a, b) 这个公式

     1  void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y)
     2 {
     3     if(!b)
     4         {d = a; x = 1; y = 0;}
     5      else
     6     {
     7         ex_gcd(b, a%b, d, y, x); 
     8         y -= x*(a/b);
     9     }    
    10 }
    View Code

    五:数论四大定理

    1.威尔逊定理:

      当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )

      或者这么写( p -1 )! ≡ p-1 ( mod p )

      或者说

      若p为质数,则p能被(p-1)!+1整除

    2.欧拉定理:

     
      若n,a为正整数,且n,a互质,即gcd(a,n) = 1,则
       a^φ(n) ≡ 1 (mod n)
     
       φ(n) 是欧拉函数
     
        欧拉函数是求 1到n-1 中 与n互质的数 的数目
     3.中国剩余定理

      假设整数m1,m2, ... ,mn两两互质,则对任意的整数:a1,a2, ... ,an,方程组 (S)有解

     1 #include<cstdio>
     2 typedef long long LL;
     3 const int N = 100000 + 5;
     4 void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
     5     if (!b) {d = a, x = 1, y = 0;}
     6     else{
     7         ex_gcd(b, a % b, y, x, d);
     8         y -= x * (a / b);
     9     }
    10 }
    11 LL inv(LL t, LL p){//如果不存在,返回-1
    12     LL d, x, y;
    13     ex_gcd(t, p, x, y, d);
    14     return d == 1 ? (x % p + p) % p : -1;
    15 }
    16 LL china(int n, LL *a, LL *m){//中国剩余定理
    17     LL M = 1, ret = 0;
    18     for(int i = 0; i < n; i ++) M *= m[i];
    19     for(int i = 0; i < n; i ++){
    20         LL w = M / m[i];
    21         ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    22     }
    23     return (ret + M) % M;
    24 }
    25 int main(){
    26     LL p[3], r[3], d, ans, MOD = 21252;
    27     int cas = 0;
    28     p[0] = 23; p[1] = 28; p[2] = 33;
    29     while(~scanf("%I64d%I64d%I64d%I64d", &r[0], &r[1], &r[2], &d) && (~r[0] || ~r[1] || ~r[2] || ~d)){
    30         ans = ((china(3, r, p) - d) % MOD + MOD) % MOD;
    31         printf("Case %d: the next triple peak occurs in %I64d days.
    ", ++cas, ans ? ans : 21252);
    32     }
    33 
    34 }
    View Code
     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long LL;
     5 typedef pair<LL, LL> PLL;
     6 PLL linear(LL A[], LL B[], LL M[], int n) {//求解A[i]x = B[i] (mod M[i]),总共n个线性方程组
     7     LL x = 0, m = 1;
     8     for(int i = 0; i < n; i ++) {
     9         LL a = A[i] * m, b = B[i] - A[i]*x, d = gcd(M[i], a);
    10         if(b % d != 0)  return PLL(0, -1);//答案不存在,返回-1
    11         LL t = b/d * inv(a/d, M[i]/d)%(M[i]/d);
    12         x = x + m*t;
    13         m *= M[i]/d;
    14     }
    15     x = (x % m + m ) % m;
    16     return PLL(x, m);//返回的x就是答案,m是最后的lcm值
    17 }
    不互质情况

    4.费马小定理:

      假如p是质数,若p不能整除a,则 a^(p-1) ≡1(mod p),若p能整除a,则a^(p-1) ≡0(mod p)。
      或者说,若p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1。
     

    六:逆元

    求单个逆元:   inv[a]=pow(a,mod-2,mod);

    求n个数的逆元: inv[0]=inv[1]=1;  inv[i]=(mod-mod/i)*inv[mod%i];

    七:欧拉函数

     1 #include<cstdio>
     2 using namespace std;
     3 const int N = 1e6+10 ;
     4 int phi[N], prime[N];
     5 int tot;//tot计数,表示prime[N]中有多少质数
     6 void Euler(){
     7     phi[1] = 1;
     8     for(int i = 2; i < N; i ++){
     9         if(!phi[i]){
    10             phi[i] = i-1;
    11             prime[tot ++] = i;
    12         }
    13         for(int j = 0; j < tot && 1ll*i*prime[j] < N; j ++){
    14             if(i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j]-1);
    15             else{
    16                 phi[i * prime[j] ] = phi[i] * prime[j];
    17                 break;
    18             }
    19         }
    20     }
    21 }
    22 
    23 int main(){
    24     Euler();
    25 }
    View Code

    八:卢卡斯定理

    求Cnm,用逆元为O(n)的。

    但若 n m 特别大,p很小的时候。

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

     

    九:康托展开

    康托的一套算法可以正好产生n!个数字

    比如:

    123  ->  0

    132  ->  1

    213  ->  2

    231  ->  3

    312  ->  4

    321  ->  5

     1 void cantor(int s[], LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度
     2     int t;
     3     bool h[k];//0到k-1,表示是否出现过
     4     memset(h, 0, sizeof(h));
     5     for(int i = 0; i < k; i ++){
     6         t = num / fac[k-i-1];
     7         num = num % fac[k-i-1];
     8         for(int j = 0, pos = 0; ; j ++, pos ++){
     9             if(h[pos]) j --;
    10             if(j == t){
    11                 h[pos] = true;
    12                 s[i] = pos + 1;
    13                 break;
    14             }
    15         }
    16     }
    17 }
    18 void inv_cantor(int s[], LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num
    19     int cnt;
    20     num = 0;
    21     for(int i = 0; i < k; i ++){
    22         cnt = 0;
    23         for(int j = i + 1; j < k; j ++){
    24             if(s[i] > s[j]) cnt ++;//判断几个数小于它
    25         }
    26         num += fac[k-i-1] * cnt;
    27     }
    28 }
    View Code

    hdu 1430(坑)

    十:抽屉原理

  • 相关阅读:
    .Net 请求Web接口Post和Get方法
    搭建 Windows Server 2012 FTP 服务器
    使用C#开发HTTP服务器系列之访问主页
    使用C#开发HTTP服务器系列之Hello World
    使用C#开发HTTP服务器系列之实现Get和Post
    HTTP网络请求原理 (三) 简单模拟HTTP服务器
    HTTP请求报文和HTTP响应报文
    HTTP协议Keep-Alive模式详解和HTTP头字段总结
    今天修了一个bug,关于debug日志的问题
    HMM(隐马尔可夫),这篇讲的不错
  • 原文地址:https://www.cnblogs.com/Kaike/p/12987450.html
Copyright © 2011-2022 走看看