#include<ctime>
#include<cstdio>
#include<cstdlib>
const int MAXN=12345;
//拓展欧几里得:返回值=gcd(a,b),x,y满足a*x+b*y=gcd(a,b),a^x≡1(mod b) 即逆元
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1,y=0;
return a;
}
int ans=exgcd(b,a%b,y,x);
y-=a/b*x;
return ans;
}
//最大公因数和最小公倍数
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
//质因数分解
int cnt,Cr[MAXN],Cl[MAXN];
void cut(int x)
{
for(int i=2;i*i<=x;i++)
if(x%i==0)
{
Cr[++cnt]=i;
while(x%i==0) Cl[cnt]++,x/=i;
}
if(x>1) Cr[++cnt]=x,Cl[cnt]=1;
}
//快速幂
int ksm(int a,int b,int c)
{
int ans=1;
a%=c;
while(b)
{
if(b&1) (ans*=a)%=c;
b>>=1; (a*=a)%=c;
}
return ans;
}
//慢速幂(快速加,以防爆int)
int mul(int a,int b,int c)
{
int ans=0;
while(b)
{
if(b&1) (ans+=a)%=c;
b>>=1; (a+=a)%=c;
}
return ans;
}
int msm(int a,int b,int c)
{
if(b==0) return 1;
if(b==1) return a%c;
int ans=msm(a,b/2,c)%c;
ans=mul(ans,ans,c)%c;
if(b%2) ans=mul(ans,a,c)%c;
return ans%c;
}
//欧拉函数
int phi(int x)
{
int k=x;
for(int i=2;i*i<=x;i++)
if(x%i==0)
{
while(x%i==0) x/=i;
k=k/i*(i-1);
}
if(x>1) k=k/x*(x-1);
return k;
}
//筛欧拉函数+筛质数
bool vis[MAXN];
int ct,eul[MAXN],p[MAXN];//p为质数数组,实际大小可以略大于MAXN/ln(MAXN)
void Shai(int N)
{
for(int i=2;i<=N;i++)
{
if(!vis[i]) p[++ct]=i,eul[i]=i-1;
for(int j=1;j<=ct&&p[j]*i<=N;j++)
{
vis[p[j]*i]=1;
if(i%p[j]==0)
{
eul[p[j]*i]=eul[i]*p[j];
break;
}
eul[p[j]*i]=eul[i]*(p[j]-1);
}
}
}
//生成N个元素的K排列
int lis[MAXN],Give[MAXN];
bool vi[MAXN];
void dfs1(int pos,int N,int K)
{
if(pos>K)
{
for(int i=1;i<K;i++)
printf("%d ",lis[i]);
printf("%d\n",lis[K]);
return ;
}
for(int i=1;i<=N;i++)
if(!vi[i]) vi[i]=1,lis[pos]=i,dfs1(pos+1,N,K),vi[i]=0;
}
//卡特兰数
int Ctl[MAXN];
void Catalan(int N)
{
Ctl[1]=1;
for(int i=2;i<=N;i++)
Ctl[i]=(4*i-2)/(i+1)*Ctl[i-1];
}
//筛1~N关于p的逆元
int ny[MAXN];
void ShaiNy(int N,int p)
{
ny[1]=1;
for(int i=2;i<=N;i++)
ny[i]=-(p/i)*ny[p%i];
}
//MillerRobin判断素数
bool MillerRobin(int p)
{
srand((unsigned)time(NULL));
if(p==2||p==3) return true;
if(p%2==0) return false;
int N=50,cnt=0,q=p-1;
while(!(q&1)) cnt++,q>>=1;
while(N--)
{
bool helper=1;
int a=rand()%(p-1)+1,v=ksm(a,q,p),k=cnt;
if(v==1||v==p-1) continue;
while(k--&&helper)
{
(v*=v)%=p;
if(v==p-1) helper=0;
}
if(helper) return false;
}
return true;
}
//第一类stirling数,把n个数分成k个环排列
int S(int n,int k)
{
if(!n||!k) return 0;
if(k==1) return 1;
return S(n-1,k-1)+(n-1)*S(n-1,k);
}
//第二类stirling数,把n个数的集合正好分为k个非空子集和
int S2(int n,int k)
{
if(n<k||!k) return 0;
if(n==k||k==1) return 1;
return S2(n-1,k-1)+k*S2(n-1,k);
}
int main()
{
}
【原创】数论模板-拓展欧几里得,质因数分解,快速幂快速加,欧拉函数筛法,欧拉函数求法,筛质数,卡塔兰数,筛逆元,第一二类斯特林数,米勒罗宾算法
最新推荐文章于 2023-04-11 19:56:38 发布