数论

2017年3月4日02:11:35

gcd

1. 原理:

gcd( a, b ) = gcd( b, a - b ) -> gcd( a, b ) = gcd( b, b % a )

2. 代码

int gcd( int a, int b ) {
if( b == 0 ) return a; return gcd( b, a % b );
}

3. 时间复杂度:

O(log n)

4. 预处理

d[3000][3000] 中所有两个数的gcd

d[i][j] = d[i][j-i];

预处理时间复杂度O(n^2)

5. 应用

1.

给一个数a,找一个(0,a)范围内的数b,gcd(a,b)=1,用a和b做辗转相减次数不超过60

(i) 构造: 直接找质数b;

(ii)gcd( b, a % b ) => O( log n )

使gcd( b, a - b ) 与gcd( b, a % b )时间复杂度一样,则自然想到斐波那契数列

例如

一组斐波那契数:

1, 1, 2, 3, 5, 8, 13, 21;

辗转相处过程:

21, 13 => 13, 8 => 8, 5 => 5, 3 => 3, 2

fib[i] / fib[ i - 1 ] -> 黄金分割,所以构造a * 0.618 附近的数

2. 斐波那契数列性质
gcd( fib[i], fib[j] ) = fib[ gcd( i, j )];
3.区间gcd
(一)

给出数组A,询问区间gcd

n < 1e5, A[i] < 1e9

线段树:

dL, dR;//左右两个子树的gcd
d = gcd( dL, dR );

时间复杂度:O(nlog^2n)

ST表:

维护区间[l, l + 2^i )

询问[ l, r ]的gcd,找最大的i满足2^i <= r - l + 1

gcd( [ l, l + 2^i ), [ r - l ) )
(二)

区间加,询问区间最大公约数

n, m <= 10 ^ 5

思想:差分;

gcd( a, b, c ) => gcd( a, b - a, c - b)
A:[ l , r ] gcd( A[l], B: [ l + 1, r])

对于数组A, 区间加 询问单点的值

对于数组B, 单点修改 询问区间gcd => 线段树

(三)

给出数组A,询问其区间gcd有多少种取值

n<=1e5,A[i]<=1e9

exgcd和中国剩余定理

exgcd

1.描述:

给出a 和b,解方程

ax + by = ( a,b )

2.求解过程

  1. 求解出一组x0, y0;
  2. 得出所有解
x = x0 + t * b / ( a, b )
y = y0 - t * a / ( a,b )

事实上

  1. b = 0 ( a, b ) = a => x = 1, y = 0
原方程等价于 b * x0 + ( a % b ) * y0 = ( a, b )
化简成 a * x + b * y = b * x0 + ( a % b ) * y0
而又有 a % b = a - [ a / b ] * b
得 a * x + b * y = b * x0 + a * y0 - [ a / b ] * b * y0
移项得 a * ( x - y0 ) = b * ( x0 - [ a / b ] * y0 - y )
令 x = y0
y = x0 - [ a / b ] * y0
构造出一组解

中国剩余定理

1. 描述

事实上,以上的过程都可以表示成

a * x = b ( mod m )

2. 求解一个过程

  1. 而当gcd( a, m ) 不是 b 的约数时显然无解
  2. 当( a, m ) | b
解出 a * X + m * Y = ( a, m )
然后解出
x = X * b / ( a, m )
y = Y * b / ( a, m )

3. 真正的中国剩余定理

x = a[i] ( mod b[i] )//有一堆
求解

例如

x = a1 ( mod b1 )
x = a2 ( mod b2 ) 使两个常数 c1, c2
有 x = a1 * b2 * c1 + a2 * b1 * c2
b2 * c1 = 1 mod b1
b1 * c2 = 1 mod b2 同样的,三组时候
有 x = a1 * b2 * b3 * c1 + a2 * b1 * b3 * c2 + a3 * b1 * b2 * c3

费马小定理

1. 描述

对于质数p,任意a∈[1, p - 1],a ^ ( p - 1 ) = 1 ( mod p )

2. 逆元(应用)

逆元定义

对于数a, b,如果存在最小整数x,使a * x = 1 ( mod b ),那么称x是a模的逆元

应用

所以直接用 a ^ ( p - 2 ) mod p 快速幂即可(可以避免exgcd)

欧拉定理

1. 描述

欧拉定理是费马小定理的拓展

欧拉函数 φ ( n ) 表示[1, n]范围内与 n 互质的数。对于任意质数 p, φ ( p ) = p - 1

欧拉定理 对于任意正整数 m, a∈[1, m - 1], gcd(a, m) = 1,都有a^φ ( m ) = 1 ( mod m )

当m为质数是,就是费马小定理的情况。所以欧拉定理是费马小定理的拓展。

2. 求φ( m )(应用)

  1. 当( a, b ) = 1 φ( a * b ) = φ( a ) * φ( b )
  2. φ( p ^ t ) = ( p - 1 ) * p ^ ( t - 1 )

    与10互质 => 与2互质

    所以将m分解质因数,结合 φ( p ) = p - 1,运用上述公式,可以求得。复杂度O( m ^ 0.5 )

3. 逆元(应用)

a的逆元就是 a^( φ ( m ) - 1) mod m

二项式系数和简单排列组合

1. 描述

C( n, m ) 从 n 个不同的球中选 m 个出来的方案数

递推式

C( n , m ) = C( n - 1, m - 1 ) + C( n - 1, m )

代码实现:

for( int i = 0 ; i <= n ; ++ i ) {
C[i][0] = 1;
for( int j = 1 ; j <= i ; ++ j ) {
C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
}
}

2. 二项式定理

对于展开 ( x + y ) ^ n, x ^ i * y ^ ( n - i ) 的系数是 C( n, i )

[杨辉三角]

**ex **对于展开 ( x + y + z ) ^ n, x ^ a * y ^ b * z ^( n - a - b ) 的系数是C( n ,a ) * C( n - a, b)

高斯消元

描述

一个方程组,如

3x + 4y = 10 ①

x + y = 3 ②

手算 消元求方程

过程:

x[i, j] 第 i 个方程第 j 个未知数的系数

  1. 先找一个方程k,满足 x[k, 1] != 0
  2. 用这个方程把僧下的方程的第一个未知数消掉
  3. 再看其他系数

    代码实现:
for( int i = 1 ; i <= N ; ++ i ) {
int where = 0;
for( int j = i ; j <= N ; ++ j )
if ( x[j][i] != 0 ) {
where = j;
break;
}
for( int j = 0 ; j <= N ; ++ j ) swap( x[where][j], x[i][j] );
for( int j = i + 1 ; j <= N ; ++ j ) {
double k1 = x[j][i] / x[i][i];
for( int k = 0 ; k <= N ; ++ k ) x[j][k] -= k1 * x[i][k];
}
}
//此时第 i 个方程只和i ~ n 个变量有关
for( int i = N ; i ; -- i ) {
ans[i] = x[i][0];
for( int j = i + 1 ; j <= N ; ++ j )
ans[i] -= x[i][j] * ans[j];
ans[i] /= x[i][i];
}
//当找不到系数不为零的时候,那么就是无解或者无限解

ARZhu的数论初步的更多相关文章

  1. 数论初步(费马小定理) - Happy 2004

    Description Consider a positive integer X,and let S be the sum of all positive integer divisors of 2 ...

  2. 数论初步——Eratosthenes筛法

    具体内容见紫书p312-p313 一.用Eratosthenes筛法构造1~n的素数表 思想:对于不超过n的每个非负整数p,删除2p,3p,4p…,当处理完所有的数后,还没有被删除的就是素数. 代码: ...

  3. 2019中山纪念中学夏令营-Day19 数论初步【GCD(最大公约数),素数相关】

    关于GCD的一些定理或运用的学习: 1. 2.二进制算法求GCD 思想:使得最后的GCD没有2(提前把2提出来) 代码实现: #include <cstdio> #define int l ...

  4. UVa第十章数学概念与方法

    Bryce1010模板 10.1数论初步 1.欧几里得算法和唯一分解定理 2.Eratosthenes筛法 补充素数筛选 const int MAXN=1e6+10; ll prime[MAXN]; ...

  5. NOIP复习之1 数学数论

    noip一轮复习真的要开始啦!!! 大概顺序是这样的 1.数学 2.搜索贪心 3.数据结构 4.图论 5.dp 6.其他 数学 1.数论 数论被称为数学皇冠上的明珠,他的重要性主要在于它是其他学习的祖 ...

  6. 移动端之Android开发的几种方式的初步体验

    目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...

  7. CSharpGL(29)初步封装Texture和Framebuffer

    +BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(29)初步封装Texture和Framebuffer +BIT祝威+悄悄在此留下版了个权的信息说: Texture和Framebuffe ...

  8. Android自定义View初步

    经过上一篇的介绍,大家对于自定义View一定有了一定的认识,接下来我们就以实现一个图片下显示文字的自定义View来练习一下.废话不多说,下面进入我们的正题,首先看一下我们的思路,1.我们需要通过在va ...

  9. 初步认识Node 之Node为何物

    很多人即便是在使用了Node之后也不知道它到底是什么,阅读完本文你应该会有一个初步的.具体的概念了.    Node的目标 提供一种简单的构建可伸缩网络程序的方法.那么,什么是可伸缩网络程序呢?可伸缩 ...

随机推荐

  1. jQuery按键事件响应的Demo

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  2. package.json 里 devDependencies和dependencies的区别

    我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,比如: --save-dev --save 在 package.json 文件里面 ...

  3. shell 命令合并文本

    之前想把代码打印出来看来着,后来合并完之后放在word里发现有2000多页,然后放弃了~anyway,这个命令还是挺有用的. 比如我有文本a001.dat, a002.dat, a003.dat .. ...

  4. 用c3m自动生成的化学机理文件导入mfix里需要注意的一些问题

    1. 首先是类似这种写法: Species_g(1) = "CH4" Species_Alias_g(1) = "CH4" 可能会报错,写在一行可能就好了,如: ...

  5. Java线程:线程交互

    一.基础知识 java.lang.Object的类的三个方法: void notify():唤醒在此对象监视器上等待的单个线程. void notifyAll():唤醒在此对象监视器上等待的所有线程. ...

  6. 用ant打包可运行的jar文件 (将第三方jar包放进你自己的jar包)

    http://blog.csdn.net/caiqcong/article/details/7618582 <span style="font-family:SimSun;font-s ...

  7. 分享一个基于thrift的java-rpc框架

    简单介绍 这是一个简单小巧的Java RPC框架,适用于Java平台内.为系统之间的交互提供了.高性能.低延迟的方案.适合在集群数量偏少的情况下使用(50台以下集群环境).当然.它也可以在大型集群环境 ...

  8. 《JAVASCRIPT高级程序设计》第一章

    在使用调制解调器的时代,频繁的表单验证对客户端来说是一个很大的负担,javascript,作为一种专门进行表单验证的客户端脚本语言诞生了.到今天,javascript早已超越了当初设定的角色.Java ...

  9. 技巧收集-W1701

    2017.02 For Flask, to use the decorator, apply it as innermost decorator to a view function. When ap ...

  10. 自己开发轻量级ORM(三)

    上一篇中简单分享了下ORM的设计思路.现在开始讲如何用代码来实现上篇的设计模型. 我们建2个类库来分别抽象数据库表结构关系映射和SQL增删改查操作. 打开VS2010,新建2个类库.分别起名为Mode ...