因子问题

典题合集

求整数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;
	}
};
posted @ 2023-12-07 16:17  White_Sheep  阅读(3)  评论(0编辑  收藏  举报