OI模板

数学部分

数论

整合包
#define LL long long 
inline LL mul(LL a,LL b,LL mod){LL ans=0;while(b){if(b&1)ans=(ans+a)%mod;a=(a+a)%mod;b>>=1;}return ans;}
inline LL pow_mul(LL a,LL b,LL mod){LL ans=1;while(b){if(b&1)ans=mul(ans,a,mod);b>>=1;a=mul(a,a,mod);}return ((ans%mod)+mod)%mod;}
inline LL poww(LL a,LL b,LL mod){LL ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1;a=a*a%mod;}return ((ans%mod)+mod)%mod;}
LL gcd(LL a,LL b){if(!b)return a;return gcd(b,a%b);}
inline LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
void exgcd(LL a,LL b,LL &x,LL &y){if(!b){x=1,y=0;return ;}exgcd(b,a%b,y,x);y-=a/b*x;}
inline LL inv_gcd(LL num,LL mod){LL x=0,y=0;exgcd(num,mod,x,y);return ((x%mod)+mod)%mod;}
inline LL inv_pow(LL num,LL mod){return poww(num,mod-2,mod);}
LL get_elr(LL x){LL res=x;for(register int i=2;i*i<=x;i++){if(!(x%i)){res-=res/i;while(!(x%i))x/=i;}}if(x>1)res-=res/x;return res;}
LL CRT(int n,LL a[],LL m[],LL M){LL ans=0;for(register int i=1;i<=n;i++){LL mp=M/m[i];x=0,y=0;exgcd(mp,m[i],x,y);ans=((ans+a[i]*mp*x)%M+M)%M;}return ans;}
LL ex_CRT(int n,LL *a,LL *m){int flag=1;for(register int i=2;i<=n;i++){LL M1=m[i-1],M2=m[i];LL A1=a[i-1],A2=a[i],d=gcd(M1,M2);if((A2-A1)%d){flag=0;break;}m[i]=M1/d*M2;a[i]=(((inv_gcd(M1/d,M2/d)*(A2-A1)/d)%(M2/d)*M1+A1)%m[i]+m[i])%m[i];}return flag?a[n]:-1;}
void sieve(int n,int pri[],int vis[],int &tot){vis[1]=1;for(register int i=2;i<=n;i++){if(!vis[i])pri[++tot]=i;for(register int j=1;i*pri[j]<=n;j++){if(!(i%pri[j]))break;vis[i*pri[j]]=1;}}}
void sieve_elr(int n,int phi[],int pri[],int vis[],int &tot){phi[1]=vis[1]=1;for(register int i=2;i<=n;i++){if(!vis[i]){pri[++tot]=i;phi[i]=i-1;}for(register int j=1;i*pri[j]<=n;j++){if(!(i%pri[j])){vis[i*pri[j]]=1;phi[i*pri[j]]=phi[i]*pri[j];break;}vis[i*pri[j]]=1;phi[i*pri[j]]=phi[i]*(pri[j]-1);}}}

快速乘
inline LL mul(LL a,LL b,LL mod)
{
	LL ans=0;
	while(b)
	{
		if(b&1)
			ans=(ans+a)%mod;
		a=(a+a)%mod;b>>=1;
	}
	return ans;
}
快速幂
inline LL poww(LL a,LL b,LL mod)
{
	LL ans=1;
	while(b)
	{
		if(b&1)
			ans=ans*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ans;
}
gcd,最大公因数,欧几里得算法
LL gcd(LL a,LL b)
{
	if(!b)
		return a;
	return gcd(b,a%b);
}
lcm,最小公倍数
inline LL lcm(LL a,LL b)
{
      return a/gcd(a,b)*b;
}
exgcd,扩展欧几里得
LL exgcd(LL a,LL b,LL &x,LL &y)
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}
求逆元(单个)
inline LL inv_gcd(LL num,LL mod)//拓展欧几里得
{
	LL x=0,y=0;exgcd(num,mod,x,y);
	return ((x%mod)+mod)%mod;
}
inline LL inv_pow(LL num,LL mod)//费马小定理
{
	return poww(num,mod-2,mod);
}
求欧拉函数(单个)
LL get_elr(LL x)
{
	LL res=x;
	for(register int i=2;i*i<=x;i++)
	{
		if(!(x%i))
		{
			res-=res/i;
			while(!(x%i))
				x/=i;
		}
	}
	if(x>1)
		res-=res/x;
	return res;
}
线性筛
void sieve(int n,int pri[],int vis[],int &tot)
{
	vis[1]=1;
	for(register int i=2;i<=n;i++)
	{
		if(!vis[i])
			pri[++tot]=i;
		for(register int j=1;i*pri[j]<=n;j++)
		{
			if(!(i%pri[j]))
				break;
			vis[i*pri[j]]=1;
		}
	}
}
欧拉筛
void sieve_elr(int n,int phi[],int pri[],int vis[],int &tot)
{
	phi[1]=vis[1]=1;
	for(register int i=2;i<=n;i++)
	{
		if(!vis[i])
		{
			pri[++tot]=i;
			phi[i]=i-1;
		}
		for(register int j=1;i*pri[j]<=n;j++)
		{
			if(!(i%pri[j]))
			{
				vis[i*pri[j]]=1;
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			vis[i*pri[j]]=1;
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
}
CRT,中国剩余定理
LL CRT(int n,LL a[],LL m[],LL M)
{
	LL ans=0;
	for(register int i=1;i<=n;i++)
	{
		LL mp=M/m[i];
		x=0,y=0;
		exgcd(mp,m[i],x,y);
		ans=((ans+a[i]*mp*x)%M+M)%M;
	}
	return ans;
}
exCRT,扩展中国剩余定理
LL ex_CRT(int n,LL *a,LL *m)
{
	int flag=1;
	for(register int i=2;i<=n;i++)
	{
		LL M1=m[i-1],M2=m[i];
		LL A1=a[i-1],A2=a[i],d=gcd(M1,M2);
		if((A2-A1)%d)
		{
			flag=0;
			break;
		}
		m[i]=M1/d*M2;
		a[i]=(((inv_gcd(M1/d,M2/d)*(A2-A1)/d)%(M2/d)*M1+A1)%m[i]+m[i])%m[i];
	}
	return flag?a[n]:-1;
}

矩阵

矩阵快速幂
struct matrix
{
	LL a[101][101]={};
	inline void build()
	{
		for(register int i=1;i<=n;i++)
			a[i][i]=1;
	}
}a;

matrix operator *(const matrix &x,const matrix &y)
{
	matrix z;
	for(register int k=1;k<=n;++k)
		for(register int i=1;i<=n;++i)
			for(register int j=1;j<=n;++j)
				z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
	return z;
}

inline matrix poww(matrix x,LL k)
{
	matrix res;
	res.build();
	while(k)
	{
		if(k&1)
			res=res*x;
		x=x*x;
		k>>=1;
	}
	return res;
}
posted @ 2021-02-03 10:55  江北南风  阅读(90)  评论(0编辑  收藏  举报