$\sqrt n$筛质因子
只能存在一个质因子大于sqrt(n),可能不存在
rep(i , 2, tmp) {
while(x % i == 0) x /= i;//如果x % i == 0,那么i为x的一个质因子
}
if(x > 1)//还存在一个质因子大于sqrt(x)
2.对于一个正整数N的素数幂分解N=$P_1^{q_1}P_2^{q_2}...P_n^{q_n}.$
$ φ(N)=N(1-1/P1)(1-1/P2)...*(1-1/Pn)$.
int phi(int x)
{
int ans = x,qwq = sqrt(x);
rep(i,2,qwq)
if(x % i == 0) {
ans = ans - ans / i;
while(x % i == 0) x /= i;
}
if(x > 1) ans = ans - ans / x;
return ans;
}
3.线性筛素数
因为phi函数是一个积性函数,所以可以线性筛出
如果$i$为质数,那么phi[i] = i - 1
否则可以通过积性函数的性质求出。
void work() {
phi[1] = 1;
vis[1] = 1;
rep(i , 2, n) {
if(!vis[i]) prime[++ num] = i,phi[i] = i - 1;
for(int j = 1;j <= num && i * prime[j] <= n;++ j) {
vis[i * prime[j]] = 1;
if(i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
4.n!在modp意义下的逆元
n!的逆元
inv[i] = inv[i + 1] * (i + 1) % p//i表示i!
5.杨辉三角求组合数
$C(n,m) = C(n - 1,m) + C(n - 1,m - 1)$
for(int i = 0;i <= 2000;++ i)
f[i][0] = 1;
for(int i = 1;i <= 2000;++ i) {
for(int j = 1;j <= i;++ j) {
f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % k;
if(!f[i][j]) sum[i][j] ++;
}
}
6.gcd(最大公因数)
int gcd(int a,int b) {return !b ? a : gcd(b , a % b);}
7.筛最小质因子
void get() {
vis[1] = 1;
for(int i = 2;i <= n;++ i) {
if(!vis[i]) {prime[++ num] = i;v[i] = i;}
for(int j = 1;i * prime[j] <= n && j <= num;++ j) {
vis[i * prime[j]] = true;
v[i * prime[j]] = prime[j];
if(i % prime[j] == 0) break;
}
}
}