• 2020/1/17 一些数论


    (不是数学课)

    标签(空格分隔): 课堂笔记


    最大公约数(gcd)

    如果d是能同时整除a, b中最大的正整数,我们称d为a和b的最大公约数,记作d = gcd(a, b)

    辗转相除法

    a > b,我们有gcd(a, b) = gcd(b, a % b)

    最小公倍数(lcm)

    如果一个数d,既是a的倍数,又是b的倍数,同时d是满足这两个条件中的最小正整数,那么称d是a和b的最小公倍数,记作d = lcm(a, b)

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

    唯一分解定理

    任意一个正整数x,都可以唯一地分解成p1^a1 * p2^a2 * … * (p_n)^(a_n)的形式,其中p1到(p_n)是素数(不考虑素数之间的顺序)

    NOIP2014 比例简化

    [原题][1]
    [1]: https://www.luogu.com.cn/problem/P2118
    可以暴力枚举,但要注意分数,计算机在计算分数的时候会失去一定的精度。

    进制

    转换:P进制下的a1a2…an代表的数字是
    a1 * p^(n-1) + a2 * p^(n-2) + … + an

    高精度

    总之就是模拟人用竖式的运算规则,进行借位,进位。
    加法

    struct Bignum
    {
    	int a[N],len;
     } 
    Bignum operator+(Bignum x,Bignum y){
     	Bignum z;
     	z.len = max(x.len,y.len);
     	for(int i = 1; i <= z; i++)
     		z.a[i] = x.a[i]+y.a[i];
     	for(int i = 1; i <= z.len; i++)
     	{
     		z.a[i+1] += z.a[i]/10;
     		z.a[i] %= 10
    	 }
    	 if(z.a[z.len+1]>0) z.len++;
    	 return z;
     }
    

    减法

    
    Bignum operator-(Bignum x,Bignum y)
    {
    	Bignum z;
    	z.len=max(x.len,y.len);
    	for(int i=1;i<=z.len;i++)
    		z.a[i]=x.a[i]-y.a[i];
    	for(int i=1;i<=z.len;i++)
    	if(z.a[i]<0)
    	{
    		z.a[i]+=10;
    		z.a[i+1]--;
    	}
    	while(z.a[z.len]==0)z.len--;
    	return z;
    }
    
    

    乘法

    Bignum operator*(Bignum x,Bignum y){
    	Bignum z;
    	z.len = x.len+y.len-1;
    	for(int i = 1; i <= x.len; i++)
    		for(int j = 1; j <= y; j++)
    			{
    				z.a[i+j-1]+=x.a[i]*y.a[i];
    			}
    	for(int i = 1; i <= z.len; i++){AS
    		z.a[i+1] += z.a[i]/10;
    		z.a[i]%=10;
    	}
    	while(z.a[z.len+1]>0){
    		z.len++;
    		z.a[z.len+1]+=z.a[z.len]/10;
    		z.a[z.len]%=10;
    	}
    	return z;
    }
    

    除法(高精除以低精)

    Bignum operator/(Bignum x,int y)
    {
    	Bignum z;
    	z.len=x.len;
    	for(int i=z.len;i;i--)
    	{
    		z.a[i]=x.a[i]/y;
    		x.a[i-1]+=10*x.a[i]%y;
    	}
    	while(z.len>1&&z.a[z.len]==0)z.len--;
    	return z;
    }
    
    

    除法(高精除以高精)

    bool operator<=(Bignum x,Bignum y)
    {
    	if(x.len<y.len)return 1;
    	if(x.len>y.len)return 0;
    	for(int i=x.len;i;i--)
    	if(x.a[i]!=y.a[i])
    	return x.a[i]<=y.a[i];
    	return 1;
    }
    Bignum shift(Bignum x,int len)
    {
    	Bignum y;
    	y.len=x.len+len;
    	for(int i=1;i<=x.len;i++)
    	y.a[i+len]=x.a[i];
    	return y;
    }
    Bignum operator/(Bignum x,Bignum y)
    {
    	Bignum z;
    	z.len=x.len;
    	for(int i=z.len;i;i--)
    	{
    		for(int k=9;k>0;k--)
    		if(shift(y,i-1)*k<=x)
    		{
    			z.a[i]=k;
    			x=x-shift(y,i-1)*k;
    			break;
    		}
    	}
    	while(z.len>1&&z.a[z.len]==0)z.len--;
    	return z;
    }
    

    (等老师的代码)

    高精度求最大公约数

    组合数

    n=n1n2n3n4....nk
    m=m1
    m2m3m4....mk
    (C_n^m)=(C_{m1}^{n1})*(C_{m2}^{n2}*)...(C_{mk}^{nk})

    筛法

    1、线性筛
    因为许多数会被重复筛掉,如6既被2筛也被3筛。
    做法:建立一个素数集合,保证每个数只被最小质因子筛掉

    矩阵乘法

    拓展欧几里得

    任意d,gcd(a,b) = d;
    都存在x,y,使ax+by = d

  • 相关阅读:
    Linux的CPU负载
    C++ 内接连与外接连
    boost 串口通信
    创建型模式--单例模式
    Python urllib与urllib2
    CodeBlocks使用boost+MinGW
    Python 线程(七):local(线程局部存储)
    Python 线程(六):Timer(定时器)
    Python 线程(五):Event
    Python 线程(四):Semphore同步
  • 原文地址:https://www.cnblogs.com/qmings/p/12207847.html
Copyright © 2020-2023  润新知