慢慢张开你的眼睛|

两只风小鱼

园龄:2年11个月粉丝:3关注:3

数学知识

数学知识


1. 判定质数、分解质因数(试除法)

时间复杂度O(n)

bool is_prime(int n){
  if(n<2)return false;
  for(int i=2;i*i<=n;i++)
    if(n%i==0)return false;
  return true;
}

2. 质数筛法(线筛)

时间复杂度O(n)

int v[N],p[N],cnt=0;
viod primes(int n)
{
  memset(v,0,sizeof v);
  for(int i=2;i<=n;i++)
  {
    if(!v[i])p[++cnt]=i;
    for(int j=1;j<=cnt&&p[j]*i<=n;j++)
    {
      v[p[j]*i]=1;
      if(i%p[j]==0)break;
    }
  }
}

3. 约数个数 和 约数之和

算法基本定理的推论

若正整数N被分解为N=p1c1p2c2...pmcm,其中ci都是正整数,pi都是质数,且满足p1<p2<...<pm

N的整约数集合可写作:

p1b1p2b2...pmbm,0bici


N的正约数个数为:

(c1+1)(c2+1)...(cm+1)=i=1m(ci+1)


N的所有正约数个数的和为:

(1+p1+p12+..+p1c1)×...×(1+pm+pm2+...+pmcm)=i=1mj=0ci(pi)j


4. 欧几里得算法

//求gcd(a,b)

a,bN,b0,gcd(a,b)=gcd(b,amodb)

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

5. 求欧拉函数(朴素、筛法)

欧拉函数

1~N中与N互质的数的个数被称为欧拉函数,记为φ(N)
若在算法基本定理中,N=p1c1p2c2pmcm,则:

φ(N)=Np11p1p21p2pm1pm=Np|N(11p)

证明:

性质1~2
  1. n>1,1nnnφ(n)/2
  2. a,b,φ(ab)=φ(a)φ(b)
积性函数


a,bf(ab)=f(a)f(b),f

性质3~6
  1. fn=i=1mpici,f(n)=i=1mf(pici)
  2. pp|np2|n,φ(n)=φ(n/p)p
  3. pp|np2n,φ(n)=φ(n/p)(p1)
  4. d|nφ(d)=n

筛法

#define ll long long
ll p[N],v[N],phi[N],cnt=0;
void init(int x)
{
	for(int i=2;i<=x;i++)
	{
		if(!v[i])p[++cnt]=i,phi[i]=i-1;
		for(int j=1;j<=cnt&&p[j]*i<=x;j++)
		{
			v[p[j]*i]=1;
			if(i%p[j]==0)phi[i*p[j]]=phi[i]*p[j];
			else phi[i*p[j]]=phi[i]*(p[j]-1);
			if(i%p[j]==0)break;
		}
	}
}

[例题]visible lattice points


6. 快速幂

#define ll long long
ll init(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1)res*=x;
		x*=x;y>>=1;
	}
	return res;
}

7. 扩展欧几里得

定理


a,b,x,y,ax+by=gcd(a,b)
//求出特解的代码

#define ll long long
void exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return d;
}
求通解

对于一般方程ax+by=c,它有解当且仅当d|c。
所以在用上述代码求解后,我们可以得到一组特解(c/d)x0,(c/d)y0
通解可表示为:

x=cdx0+kbd,y=cdy0kbd(kZ)


8. 逆元

费马小定理

若正整数a,n互质,则aφ(n)1(modn)

乘法逆元

若整数b,p互质,并且b|a,则存在一个整数x,使得a/bax(modp)。称x为b的模m的乘法逆元,记为b1(modp)

因为a/bab1a/bbb1(modp),所以bb11(modp)

如果p是质数并且b<p,由费马小定理得,bp11(modp),bbp21(modp)因此,当模数p为质数时,bp2即为b的乘法逆元。


9. 中国剩余定理/扩展

m1,m2,,mn是两两互质的整数,m=i1nmi,Mi=m/mi,ti是线性同余方程Miti1(modmi)的一个解。对于任意的n个整数a1,a2,,an,方程组

{xa1(modm1)xa2(modm2)xan(modmn)

有整数解,解为x=i=1naiMiti

#define ll long long
ll n,m=1;

ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0){x=1,y=0;return a;};
	ll d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return d;
}

ll get(ll a,ll b,ll p)
{
	ll res=0;
	while(b)
	{
		if(b&1)res=(res+a)%p;
		a=(a+a)%p;
		b>>=1;
	}
	return res;
}

int main()
{
	scanf("%lld",&n);
	ll ans=0,x,y,d,a,b,c;
	ll a0,m0;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a,&b);
		if(i==1)
		{
			a0=a,m0=b;
			continue;
		}
		d=exgcd(a0,a,x,y);
		c=((b-m0)%a+a)%a;
		x=get(x,abs(c/d),a/d);
		m0=x*a0+m0;
		a0=(a0/d)*a;
	}
	ans=(m0%a0+a0)%a0;
	printf("%lld",ans);
	return 0;
}

10. 矩阵乘法

定义

Anm矩阵,Bmp矩阵,则C=ABnP矩阵,并且i[1,n],j[1,p]:

Ci,j=k=1mAi,kBk,j

//矩阵乘法满足结合律,满足分配律,不满足交换律

单位矩阵

[100010001]

矩阵快速幂

#define ll long long
ll n,k;
ll A[N][N],mod=1e9+7;

void multi(ll c[][N],ll a[][N],ll b[][N])
{
	ll tmp[N][N]={0};
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		for(int s=1;s<=n;s++)
		tmp[i][j]+=a[i][s]*b[s][j]%mod,tmp[i][j]%=mod;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		c[i][j]=tmp[i][j]%mod;
	}
}

void init(ll k)
{
	ll res[N][N]={0};
	for(int i=1;i<=n;i++)
		res[i][i]=1;
	while(k)
	{
		if(k&1)
		{
			multi(res,res,A);
		}
		multi(A,A,A);
		k>>=1;
	}
}

11. 高斯消元

高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵。
原线性方程组 ——> 高斯消元法 ——> 下三角或上三角形式的线性方程组 ——> 前向替换算法求解(对于上三角形式,采用后向替换算法)

image

思路如下:

image

解为:

image

求解步骤

  1. 将当前要求的未知数系数绝对值最大的一行交换到上面;

  2. 将不包括该行在内的下面所有行该未知数的系数都化为这个最大的系数;

  3. 以下所有行都减去该行;

  4. 换下一个未知数,然后重复操作;

  5. 显然,当做完一轮这样的操作后,下面的所有行里当前未知数的系数都为 0,也就是少了一个未知数;
    如果对整个矩阵都这样操作过后,最终得到的矩阵一定是一个倒三角(梯形)的形状;

  6. 做完一轮以上操作,再从下往上扫,如果有解,则最后一行的方程一定是 axn=b(a≠b),则 xn 可以解出,再代回上一个方程即可解出 xn−1。以此类推,就可以解出所有解;

解的情况

  • 无解

    在正推或倒推的时候,如果出现形如 0=b(b≠0) 的式子,则方程一定无解;

  • 无数解

    在正推或倒推时,都没有出现无解的情况;
    正推和倒推过程中产生的不是 0=0 这样的式子不足 n 个;

  • 唯一解

    正推和倒推过程中没有无解现象;
    最后剩下的不是 0=0 的式子恰好 n 个;

int n,id[N];
double ans[N],b[N],a[N][N];

int get_max(int i,int tmp)
{
	double maxx=0;tmp=0;
	for(int j=i;j<=n;j++)
		if(fabs(a[id[j]][i])>maxx)
		{
			maxx=abs(a[id[j]][i]);
			tmp=j;
		}
	return tmp;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			scanf("%lf",&a[i][j]);
		scanf("%lf",&b[i]);
		id[i]=i;
	}
	for(int i=1;i<=n;i++)
	{
		int tmp=get_max(i,tmp);
		if(tmp==0)
		{
			printf("No Solution\n");
			return 0;
		}
		swap(id[tmp],id[i]);
		for(int j=i+1;j<=n;j++)
		{
			a[id[i]][j]/=a[id[i]][i];
		}
		b[id[i]]/=a[id[i]][i];
		a[id[i]][i]=1;
		for(int j=i+1;j<=n;j++)
		{
			double t=a[id[j]][i]/a[id[i]][i];
			a[id[j]][i]=0;
			for(int k=i+1;k<=n;k++)
			{
				a[id[j]][k]-=t*a[id[i]][k];
			}
			b[id[j]]-=t*b[id[i]];
		}
	}
	for(int i=n-1;i>=1;i--)
	{
		for(int j=n;j>i;j--)
		{
			b[id[i]]-=a[id[i]][j]*b[id[j]];
			a[id[i]][j]=0;
		}
	}
	for(int i=1;i<=n;i++)
	{
		printf("%.2f\n",b[id[i]]);
	}
	return 0;
}

12. 求组合数(递推、公式、预处理逆元、lucas定理)

  1. 加法原理:
    若完成一件事有n种方法,第i种方法有ai种方案,且事件之间互不影响,则一共有a1+a2++an种方案

  2. 乘法原理:
    若完成一件事有n个步骤,第i个步骤有pi种方案,且这些步骤互不干扰,则一共有p1p2pn种方案

  3. 排列数
    从n个不同元素中依次取出m个元素排成一列,产生的不同排列的数量为:

Anm=n!(nm)!=n(n1)(nm+1)

  1. 组合数
    从n个不同元素中依次取出m个组成一个集合(不考虑顺序),产生的不同集合数量为:

Cnm=n!m!(nm)!=n(n1)(nm+1)m(m1)21

  1. 性质

    1. Cnm=Cnnm
    2. Cnm=Cn1m+Cn1m1
    3. Cn0+Cn1+Cn2++Cnn=2n
  2. Lucas定理
    若p是质数,则对于任意整数1mn,有:

CnmCnmodpmmodpCn/pm/p(modp)

也就是把n和m表示成p进制数,对p进制下的每一位分别计算组合数,最后再乘起来。

  1. Catalan数列
    给定n个0和n个1,它们按照某种顺序排成长度为2n的序列,满足任意前缀0的个数都不少于1的个数的序列的数量为:

Catn=C2nnn+1

推论:
以下问题都与Catalan数有关:
1.

13.

posted @   两只风小鱼  阅读(118)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起