快速幂
//快速幂 x^n%p ll qpow(ll x,ll n){ ll res=1; while(n){ if(n&1) res=res*x%p; x=x*x%p; n>>=1; } return res%p; //要记得模p,否则输入一个2的幂次模1就挂了 }
快速乘
//快速乘 a*b%p 防止乘法溢出ll ll qmut(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; }
费马大定理
欧拉定理
欧拉函数 积性
d(n)n的因子个数
sigma(n) n的因子之和
这些都是积性的
狄利克雷卷积
设函数 $f(x)$ 和 $g(x)$ ,则他们的狄利克雷卷积 $f*g(x)=sumlimits_{d|x}f(d)g(frac{x}{d})$
两个积性函数的狄利克雷卷积也是积性的
杜教筛
扩展欧几里得算法:
//扩展欧几里得算法:返回 g=gcd(a,b) ,以及对应的等式 ax+by=g 的解 ll extend_gcd(ll a,ll b,ll &x,ll &y){ if(a==0&&b==0) return -1; if(b==0){ x=1; y=0; return a; } ll d=extend_gcd(b,a%b,y,x); y-=a/b*x; return d; } //扩展欧几里得算法求逆元,只要求 a,mod 互质 ll inv2(ll a,ll mod){ ll x,y; ll d=extend_gcd(a,mod,x,y); if(d==1) return (x%mod+mod)%mod; return -1; }
更快的判断单独判断素数:
bool is_prime(int n) { if(n==1) return false; if(n==2||n==3) return true; if(n%6!=1&&n%6!=5) return false; for(int i=5;i*i<=n;i+=6) if(n%i==0||n%(i+2)==0) return false; return true; }
接近原本判断法的2倍速度。
线性筛/欧拉筛
const int MAXN=10000; bool is_prime[MAXN+5]; int prime[MAXN+5], cntp = 0; //实际上素数的个数大约是MAXN/ln(MAXN)个 void get_prime(int n) { memset(is_prime,1,sizeof(is_prime)); is_prime[0]=is_prime[1]=0; for(int i =2; i<=n; i++) { if(is_prime[i]) prime[cntp++]=i; for(int j=0; j<cntp&&i*prime[j]<= n; j++) { is_prime[i*prime[j]]=0; if(i%prime[j]==0) break; } } //printf("cntp=%d ",cntp); /*for(int i=0;i<=n;i++){ if(is_prime[i]) printf("%d ",i); }*/ }