怎麼篩?
\(通常來說,只要知道f(P^k),P爲質數,就能夠知道怎麼篩了\)
\(簡單來說就是推一下\)
\(通俗來說就是手玩一下或者打表找規律\)
若是你一眼就看出來了那就只能Orz了html
Bzoj4804: 歐拉心算
BZOJ2693jzptab
BZOJ4407 :於神之怒增強版數組
這個比較簡單,\(\mu(1)=1\),\(i\)爲質數時\(\mu(i)=-1\),最小質因子篩到它的時候正負號反過來,不然爲\(0\)函數
isprime[1] = 1; mu[1] = 1; for(int i = 2; i < N; ++i){ if(!isprime[i]){ prime[++num] = i; mu[i] = -1; } for(int j = 1; j <= num && i * prime[j] < N; ++j){ isprime[i * prime[j]] = 1; if(i % prime[j]) mu[i * prime[j]] = -mu[i]; else{ mu[i * prime[j]] = 0; break; } } }
求一個數在模p意義下的逆元
設\(p=i*x+j\),則\(i*x+j\equiv0(mod\ p)\)
同時除以\(i*j,因此x*j^{-1}+i^{-1}\equiv0(mod\ p)\)
移項\(i^{-1}\equiv-x*j^{-1}(mod\ p)\)
而\(x=p\ div\ i,j=p\ mod\ i\)
因此\(inv(i)=-inv(p\%i)*(p/i)\)
不用篩了,遞推就能夠了ui
inv[1] = 1; for(int i = 2; i < p; ++i) inv[i] = -(p / i) * inv[p % i] % p + p) % p;
補充階乘逆元的遞推,求出\(inv(n)\),\(inv(i)=inv(i+1)*(i+1)\)倒着來就好了spa
fac[0] = inv[0] = 1; for(int i = 1; i <= n; ++i) fac[i] = fac[i] * i % p; inv[n] = Getinv(fac[n]); //Exgcd or Fermat for(int i = 1; i < n; i++) inv[i] = inv[i + 1] * (i + 1) % p;
公式:
\(n分解成若干質數p的乘積n=\Pi p_i^{a_i}\)
\(\varphi(n)=n*\Pi(1-\frac{1}{p_i})\)code
那麼\(\varphi(1)=1\),\(n爲質數時\varphi(n)=n-1\),最小質因子篩到它時乘上質因子\(p-1\),不然乘上這個質數htm
isprime[1] = 1; phi[1] = 1; for(int i = 2; i < N; ++i){ if(!isprime[i]){ prime[++num] = i; phi[i] = i - 1; } for(int j = 1; j <= num && i * prime[j] < N; ++j){ isprime[i * prime[j]] = 1; if(i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j] - 1); else{ phi[i * prime[j]] = phi[i] * prime[j]; break; } } }
公式:
仍是分解
\(d(n)=\Pi(a_i + 1)\)blog
咱們記錄下每一個數最小質因子的指數記爲\(pred\)就行了get
isprime[1] = 1; d[1] = 1; for(int i = 2; i < N; ++i){ if(!isprime[i]){ prime[++num] = i; d[i] = 2; pred[i] = 1; } for(int j = 1; j <= num && i * prime[j] < N; ++j){ isprime[i * prime[j]] = 1; if(i % prime[j]){ d[i * prime[j]] = d[i] * d[prime[j]]; pred[i * prime[j]] = 1; } else{ pred[i * prime[j]] = pred[i] + 1; d[i * prime[j]] = d[i] / (pred[i] + 1) * (pred[i] + 2); break; } } }
公式:
又是分解
\(\sigma(n)=\Pi(\sum_{j=0}^{a_i}p_i^j)\)class
這個就很煩了。。。
也能夠篩,開兩個個數組,一個\(powd\)記錄每一個數最小質因子的指數次冪,另外一個\(sumd\)記錄每一個數最小質因子\(\sum_{i=0}^{a}p^i\)就能夠了
咱們把這個鬼裏鬼氣的\(\sigma寫成f\)
isprime[1] = 1; f[1] = mu[1] = 1; for(int i = 2; i < N; ++i){ if(!isprime[i]){ prime[++num] = i; f[i] = i + 1; mu[i] = -1; sumd[i] = 1 + i; powd[i] = i; } for(int j = 1; j <= num && i * prime[j] < N; ++j){ isprime[i * prime[j]] = 1; if(i % prime[j]){ sumd[i * prime[j]] = 1 + prime[j]; powd[i * prime[j]] = prime[j]; f[i * prime[j]] = f[i] * f[prime[j]]; } else{ powd[i * prime[j]] = powd[i] * prime[j]; sumd[i * prime[j]] = sumd[i] + powd[i * prime[j]]; f[i * prime[j]] = f[i] / sumd[i] * sumd[i * prime[j]]; break; } } }