因子问题
典题合集
求整数n的因子数
时间复杂度:\(O(\sqrt{n})\)
//获取n的不重复因子数数组
vector<int> findFactors(ll n){
vector<int> res;
for(int i=1;i<=n/i;i++){
if(n%i==0){
if(i==n/i){
res.push_back(i);
}else{
res.push_back(i);
res.push_back(n/i);
}
}
}
return res;
}
求整数n的质因子并统计个数
时间复杂度:\(O(\sqrt{n})\)
int a[100010],idx;
int b[100010];
void init(int n){
for(int i=2;i<=n/i;i++){
if(n%i==0){
a[idx]=i;
while(n%i==0){
b[idx]+=1;
n/=i;
}
idx+=1;
}
}
if(n>1) a[idx]=n,b[idx++]+=1;
}
求n个整数(1~n)的质因子
时间复杂度:O(nloglogn)
时间复杂度证明:质数的调和级数
const int N=30010;
vector<int> cnt[N];
void init(){
for(int i=2;i<N;i++){
if(cnt[i].empty()){
for(int j=i;j<N;j+=i){
cnt[j].push_back(i);
}
}
}
}
求阶乘n!中每个质因子和个数
int prime[1000],cnt=0,rat[1000];
bool p[1000];
void findprime(int n)//欧拉筛来找素数
{
for (int i = 2; i <= n; i++)
{
if (!p[i])
prime[cnt++] = i;
for (int j = 0; j < cnt; j++)
{
if (i*prime[j] > n)break;
p[i*prime[j]] = true;
if (i%prime[j] == 0)break;
}
}
}
int rate(int n, int p)//分解质因数,求得每个质因数在n!中的出现个数
{
int res = 0;
while (n)
{
res += n / p;
n /= p;
}
return res;
}
void solve(){
int n, m;
cin>>n>>m;
findprime(n);
for (int i = 0; i < cnt; i++)
rat[i] = rate(n, prime[i]) - rate(m, prime[i]) - rate(n - m, prime[i]);//计算每个质因数的幂的次数
}
求\(a^b\)的因子和
既然要求因子和,那我们必然要先分解质因数
根据整数的唯一分解定理,整数a进行质因数分解对应的式子唯一,有:
\[a=p_1^{k_1}*p_2^{k_2}*p_3^{k_3}*\ldots*p_n^{k_n}
\]
\(a^b\)的质因子分解:
\[a^b=p_1^{k_1*b}*p_2^{k_2*b}*p_3^{k_3*b}*\ldots*p_n^{k_n*b}
\]
因子和:每一项用等比数列求和求。
\[ans=(1+p_1^1+p_1^2+p_1^3+\ldots+p_1^{k_1*b})*(1+p_2^1+p_2^2+p_2^3+\ldots+p_1^{k_2*b})*\ldots*(1+p_n^1+p_n^2+p_n^3+\ldots+p_n^{k_n*b})
\]
等比数列前n项和:
\[{\textrm{当}}{\mathfrak{q}}{\neq}1{\mathfrak{时}},S_{n}={\frac{a_{1}\left(1-q^{n}\right)}{1-q}}{\mathfrak{或}}S_{n}={\frac{a_{1}-a_{n}\times q}{1-q}}
\]
\[\text{当}\mathfrak{q}=1\text{时},S_{n}=n\times a_{1}(q=1)
\]
当(x-1)=== k*mod:(x-1)不存在逆元,我们需要进行特判,但前n项和为n。
struct power {//a^b的因子和
ll f[10010][2], cnt = 0;
const ll mod = 9901;//mod需要根据题目要求进行更改。
ll qmi(ll a, ll b) { //快速幂
ll res = 1;
while (b) {
if (b & 1) {
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res % mod;
}
ll get(int a, int b) {//求a^b的因子和模mod
a = a, b = b;
if (a == 0) return 0;
ll res = 1;
for (int i = 2; 1LL * i * i <= a; i++) {//求质因子和数量
if (a % i == 0) {
cnt ++;
f[cnt][0] = i;
f[cnt][1] = 1;
a = a / i;
while (a % i == 0) {
f[cnt][1]++;
a = a / i;
}
}
}
if (a > 1) {
cnt++;
f[cnt][0] = a;
f[cnt][1] = 1;
}
function<ll(ll, ll)> sum = [&](ll x, ll y) {
ll res = 0;
y *= b;
if (x % mod == 1) {//(x-1)%mod==0:不存在乘法逆元,存在x>mod的情况
res = (y + 1) % mod; //当逆元不存在时
} else {
res = (qmi(x % mod, y + 1) - 1) % mod * qmi((x - 1) % mod, mod - 2) % mod; //当逆元存在时
}
return res % mod;
};
for (int i = 1; i <= cnt; i++) {
res = res * sum(f[i][0], f[i][1]) % mod;
}
return (res+mod)%mod;
}
};