博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ACM - 第10章 数论
阅读量:5820 次
发布时间:2019-06-18

本文共 2469 字,大约阅读时间需要 8 分钟。

10.1.1 除法表达式

gcd递归层数最多4.785lgN + 1.6723, N = max(a, b)

cint gcd(int a, int b){    return b == 0 ? a : gcd(b, a % b);}

10.1.2 无平方因子数

主要讲的是素数的问题.

Eratosthenes 筛法

cmemset(vis, 0, sizeof(vis));for(int i = 2; i <=n ;i++)    for(int j = i*2; j <=n; j+= i) vis[j] = 1;

由此一来就可以筛选出素数,不过不是线性筛法,相信佳哥也一定知道...

循环的总次数小于n/2 + n/3 + ... n/n = o(nlogn)

欧拉1734年的结果: 1 + 1/2 + 1/3 + .. 1/n = ln(n+1) + y

允许在 $10^6$ 以内的所有素数.

  • 通过素数定理求素数的个数:

PI(x) ~ x/lnx

10.1.3 直线上的点

扩展欧几里德算法求解.

g = gcd(a,b), 方程解为(x0c/g, y0c/g)

cvoid gcd(int a, int b, int& d, int& x, int& y){    if(!b) { d = a; x = 1; y = 0;}    else { gcd(b, a%b, d, y, x); y -= x*(a/b); }}

10.1.4 同余模算数

公式

(a+b) mod n = ((a mod n) + (b mod n)) mod n(a-b) mod n = ((a mod n) - (b mod n) + n) mod nab mod n = (a mod n)(b mod n) mod n

乘法取余

cint mul_mod(int a, int b, int n){    a %= n; b %=n;    return (int)((long long) a * b % n);}

大整数取MOD

cint big_int(char *n, int m){    int len = strlen(n);    int ans = 0;    for(int i = 0; i < len; i++)        ans = (int)(((long long)ans * 10 + (n[i]-'0')) % m);    return ans;}

幂取模

cint pow_mod(int a, int n, int m){    int x = pow_mod(a, n/2, m);    long long ans = (long long)x * x % m;    if (n % 2 == 1)        ans = ans * a % m;    return (int) ans;}

模线性方程

有一处没看明白,为何ax-b是n的正整数倍,而不是(a-b)x?

10.2.1 杨辉三角和二项式定理

给定n求(a+b)^n所有项的系数

c    memset(C, 0, sizeof(C));    for(int i = 0; i <= n; i++)    {        C[i][0] = 1;        for(int j = 1; j <= n; j++) C[i][j] = C[i-1][j-1] + C[i-1][j];    }
  • 10-4

提供一种思路,就是大数字的乘除法可以借用素数和指数来表示.

10.2.2 数论中的计数问题

  • 10-5

分解质因数

  • 10-6 小于n且与n互素的数的个数

欧拉函数

cint euler_phi(int n){    int m = (int) sqrt(n + 0.5);    int ans = m;    for(int i = 2; i <= m; i++) if(n % i == 0)    {        ans = ans / i*(i-1);        while(n % i == 0) n /= i;    }    if(n > 1) ans = ans/n * (n-1);    return ans;}// 筛法求范围内的欧拉函数 void phi_table(int n, int *phi){    for(int i = 2; i <= n; i++) phi[i] = 0;    phi[1] = 2;    for(int i = 2; i <= n; i++) if(!phi[i])        for(int j = i; j <= i; j+= i)        {            if(!phi[j]) phi[j] = j;            phi[j] = phi[j] / i * (i-1);        }}

编码解码

编码解码更多的利用树来构造.

10.2.4 离散概率初步

  • 生日的问题

边乘边除

cdouble birthday(int n, int m){    double ans = 1.0;    for(int i = 0; i < m ;i++) ans *= (n-1)/n;    return 1-ans;}

10.3.1 汉诺塔

利用数学归纳法来证明问题

10.3.2 Fibonacci数列

递推式,1,1,2,3,5,8...

10.3.3 Catalan 数

凸多边形的三角划分数量,车入栈出站方法均是卡特兰数.

计算方法

$f(n) = f(2)f(n-1) + f(3)f(n-2) + ... f(n-1)f(2)$

或者

$f(n+1) = (4n-6)/n * f(n)$

1,2,5,14,42,132,429,1430,4862,16796.

10.3.4 危险的组合

转载地址:http://oizdx.baihongyu.com/

你可能感兴趣的文章
$\frac{dy}{dx}$ 是什么意思?
查看>>
Go开发之路(目录)
查看>>
RHEL6.5安装成功ORACLE11GR2之后,编写PROC程序出错解决方法
查看>>
(50)与magento集成
查看>>
Ubuntu设置python3为默认版本
查看>>
日期Calendar/Date的用法
查看>>
JsonCpp 的使用
查看>>
问题账户需求分析
查看>>
JavaSE-代码块
查看>>
爬取所有校园新闻
查看>>
32、SpringBoot-整合Dubbo
查看>>
python面向对象基础
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
docker 下 安装rancher 笔记
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>
微信小程序蓝牙连接小票打印机
查看>>
环境错误2
查看>>
C++_了解虚函数的概念
查看>>