数论学习小记 其之一 基础数学

记得一位大牛说过:计算机是人造学科,数学是神造学科。练过一段时间ACM,只记得比赛时只要和数学有关的题目都十分难搞。。。。
原来的博客中对知识点的总结比较零散,希望能在新博客中做一个系统的总结吧,但毕竟时间有限,想留出更多的时间去刷题(其实就是懒……),预计会大量引用自己csdn的博文和其他人的博客。

  • 基本知识

(1)(x+y)%p=(x%p+y%p)%p;
(2)(x-y)%p=((x%p-y%p)%p+p)%p;
(3)x*y%p=((x%p)*(y%p))%p。

注意除法是不满足上述取模的规律的,除法取模需要用到乘法逆元,后面会讲到。取模次数过多会严重影响程序运行速度,具体题目具体分析,许多不必要的取模是可以省略的。

  • 二分幂

二分幂又叫快速幂,算法的本名貌似是:蒙哥马利幂模。

它的主要功能是计 算 a^b%p( 模 p 可 有 可 无 ) 。

举个例子:不妨设 a=107,b=102,p=1000000007,如果我们求出了 x=a^51%p, 那么 x^2%p就是答案。那么下面就是求 a^51:我们求出了 x=a^25,那么 x^2*a就是答案。

更具体的描述参见:Hdu 4506 小明系列故事——师兄帮帮忙 +Hdu 1420 (蒙哥马利幂模算法)

和 二分求幂(pow的logn算法) - 枫轩缘 这里有图解、递归写法、非递归写法

//蒙哥马利幂模算法
//快速幂
//返回值(s^index)%mod
__int64 Cal (__int64 s,__int64 index,__int64 mod)
{
    __int64 ans=1;
    s%=mod;
    while (index>=1)
    {
        if ((index&1)==1)   //奇数
            ans=(ans*s)%mod;
        index>>=1;
        s=s*s%mod;
    }
    return ans;
}

上面这种写法还是比较完善的,目前没有被题卡过时间。目前做过的类型有:卡取模次数的(取多了TLE,取少了显然就爆__int64),卡先对底数取模的……

  • 单个素数的判定:

从 2 到根号 n 枚举,判断是不是 n 的因子以判断 n 是不是素数。

  • 筛法求素数

常用的方法大家都叫它“素数筛法”,其实它是有名字的:埃拉托斯特尼筛法

wiki对它有很详细的描述(英文的):Sieve of Eratosthenes

算法的基本思想是一个素数的除它本身外的所有倍数均为合数。下图(转自wiki)非常直观的描述了该素数筛法的基本原理:

素数筛法

具体实现:基本思想是首先标记所有数字为 0,然后从前向后找标记为 0 的,然后将该数的倍数(倍数大于等于 2)的数标记为 1。

const int NUM=1000004;
int prime[79000],np=0;
bool tag[NUM];

__int64 n;

void Prime ()     //素数打表prime数组从0开始,范围内最大1000003
{//共np个素数,保存在prime[0]~prime[np-1]
    for (int i=2;i<NUM;i++) if (tag[i] == false)
    {   
        prime[np++]=i;
        for (int j=i+i;j<NUM;j+=i)
            tag[j]=true;
    }
}

一点补充:第二重循环可以改成 int j=i*i; 因为对于一个数x,假设它含有质因子i,那么令y=x/i;可以发现,如果x是小于i*i的数,那么其y值必小于i,在以前的筛选y的过程中,就会把x筛掉,所以没有必要重新筛选一遍。但是要注意两个int相乘有可能超范围……所以通常写作i+i,并没有慢太多。

  • 约数个数

设 n=p1^e1*p2^e2*……pk^ek(pi均为素数,两两不等,ei为指数),则 n 的约数的个数为: (e1+1)*(e2+1)*……(ek+1)。这个用排列组合很容易证明。

例:12=2^2*3^1,那么 12的约数个数为(2+1)*(1+1)=6。

  • 约数和

设 n=p1^e1*p2^e2*……pk^ek(pi均为素数,两两不等,ei为指数),则 n 的所有约数的和为:(p1^0+p1^1+ … … p1^e1)* … …(pk^0+pk^1……+pk^ek)。

例:12=2^2*3^1,那么 12 的约数和为:(2^0+2^1+2^2)*(3^0+3^1)=28。

 

给出数字 n,用 prime数组求出 n 的每个质因子以及质因子出现的个数

const int N=1;
long long p[N],pNum[N],Num;

void split (long long n)
{
    Num=0;//np为素数个数,注意int相乘有可能会超int可表示的范围
    for (int i=0;i<np && (long long)prime[i]*prime[i]<=n;i++)
    {
        if (n%prime[i]==0)
        {
            p[Num]=prime[i];
            pNum[Num]=0;
            while(n%prime[i]==0)
            {
               pNum[Num]++;
               n/=prime[i];
            }
            Num++;
        }
    }
    if (n>1) p[Num]=n,pNum[Num++]=1;
}
  • 欧拉函数

欧拉函数 phi(n)表示小于n 的正整数中与 n 互质的数的个数。比如 phi(1)=1,phi(2)=1,phi(3)=2,phi(4)=2。

  • 单个数字欧拉函数的求法

设p1,p2……pk是n的k个质因数,f(n)=n*(1-1/p1)*……(1-1/pk)。

比如n=12,则p1=2,p2=3,那么f(12)=12*(1-1/2)*(1-1/3)=4。

int Euler (int n)
{
    int i,ans=n;
    for (i=2;i*i<=n;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;
}
  • 欧拉函数的筛法

给出 N,求出 N 之内的每个数的欧拉函数。基本思想是枚举素数,判断该素数是哪些数字的质因子。

//求1到N的所有数的欧拉函数
const int N=5000005;
i64 phi[N];

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

 

  • 最大公约数

求两个数字 n 和 m 的最大公约数。欧几里得算法。

int Gcd (int x,int y)
{
    return !y?x:Gcd(y,x%y);
}
  • 最小公倍数

Lcm(x,y)=x/Gcd(x,y)*y。

  • 扩展欧几里得定理

给定两个数 a,b, 设 Gcd(a,b)=d, 则存在整数x,y,使得 x*a+y*b=d。

  • 扩展欧几里得算法

就是上述方程中给定 a 和 b 求出 x,y。

我们知道,Gcd(a,b)=Gcd(b,a%b),而我们也就是运用这个东西来求a和b的最大公约数的 。因此,bx1+(a%b)y1=d, 由于 a%b=a-a/b*b,所以 bx1+(a-a/b*b)y1=d,所以:ay1+b*(x1-a/b*y1)=d。所以若 ax+by=d,那么显然 x=y1,y=x1-a/b*y1。注意,x,y可能是负值。

i64 Extended_Euclid (i64 a,i64 b,i64 &x,i64 &y)
{//扩展欧几里得算法,求ax+by=gcd(a,b)的一组解(x,y),d=gcd(a,b)
    i64 d;
    if (b==0)
    {
        x=1;y=0;
        return a;
    }
    d=Extended_Euclid(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

这个程序返回值为 Gcd(a,b),得到的 x 和 y 满足:ax+by=Gcd(a,b)。当然,如果给出的是求 ax+by=c(c不一定是 a 和 b 的最大公约数),这时当且仅当 Gcd(a,b)可以整除 c 时存在 x 和 y。 先求 ax+by=d 的一组解 x0,y0,设 k=c/d,x=x0*k,y=y0*k,则 x 和 y 就是一组解。通解为:X=x+t*b,Y=y-t*a。 (t 为任意整数)

  • 乘法逆元

扩展欧几里得可以求乘法逆元。 乘法逆元的意思就是对于 a,p,若存在 b 使得 ab%p=1,则称 b 为 a 对 p 的乘法逆元。那么这个 b 有什么意思呢?对于一个数 x,x/a%p=x*b%p(a 可以整除 x) 。这样的话,就可以将除法变为乘法。那么怎么求 b 呢?ab%p=1,我们可得ab=kp+1(k 为某个整数),即 ab-kp=1,令 x=b,y=-k,则我们求出ax+py=1的一组解x,y即可。 这个式子有解的充要条件是Gcd(a,p)=1.

 

  • 扩展阅读

#define i64 __int64
//求前n个数的约数个数和

i64 a[10]={0,1,3,5,8,10}; 
i64 f (i64 m) 
{ 
    if (m <=5) return a[m];
    i64 sum = 0; 
    i64 i;
    for (i = 1; i*i <= m; ++i)
        sum += m/i - (i - 1);
    return sum*2-i+1; 
}

/*
数形结合,求在双曲线x*y = n在第一象限分支中下方的整点的个数。
作直线x=y,于是可以先计算上半部分(含x=y这条直线)的点数。
x=1的时候有m个,x=2的时候有m/2-1个。。。
于是乘以2。
然后x=y这条直线上的i-1个点多计算了一次,于是要减去(i-1)个。*/

一些收藏的博文

欧拉函数 - 孟起 - 博客园

当我真正理解了扩展欧几里得定理 - Accept - 博客园

求N的阶乘约数的个数 - M.J的blog - C++博客

【数论内容】线性筛素数,线性筛欧拉函数,求前N个数的约数个数 - M.J的blog - C++博客

【C/C++】位运算简介及实用技巧(二):进阶篇(1) - 八月照相馆的日志 - 网易博客

用位运算生成下一个含有k个1的二进制数 - Yang Enzo - 博客园

POJ数学题目(转载)_依然_新浪博客

数论四大定理小结(初级) - Bright-XL - 博客频道 - CSDN.NET

 

转载于:https://www.cnblogs.com/whyorwhnt/p/3488121.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值