[拆分质因数] 求1e6区间内的数的因数之和 GYM 101652C

https://vj.e949.cn/f8d37a96d021442108f4492dfd021271?v=1541730304

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;

const int mn = 1e6;

int cnt;
bool prime[mn + 10];
int pm[mn + 10];
void Prime()   /// 1e6之内素数表
{
	for (int i = 1; i <= mn; i++)
		prime[i] = 1;

	for (int i = 2; i <= mn; i++)
	{
		if (prime[i] == 0)
			continue;

		pm[++cnt] = i;
		for (int j = 2; i * j <= mn; j++)
			prime[i * j] = 0;
	}
}

ll L, R;
ll val[mn + 10], num[mn + 10][20];
int pcnt[mn + 10], ecnt[mn + 10][20];
void find_prime()
{
	for (int i = 0; i <= R - L; i++)
		val[i] = L + i;

	for (int i = 1; i <= cnt; i++)
    {
        for (ll j = (L - 1) / pm[i] * pm[i] + pm[i]; j <= R; j += pm[i])    /// 范围内每pm[i]个 因数含pm[i]
        {
            ll id = j - L;
            pcnt[id]++;     // id的因子数+1
            num[id][pcnt[id]] = pm[i];  // 该因子值为pm[i]
            while (val[id] % pm[i] == 0)
            {
                val[id] /= pm[i];
                ecnt[id][pcnt[id]] ++;  // 该因子个数
            }
        }
    }
    
    for (int i = 0; i <= R - L; i++)
    {
        if (val[i] > 1)     /// 有且只有一个大于1e6的因子
        {
            pcnt[i]++;
            num[i][pcnt[i]] = val[i];
            ecnt[i][pcnt[i]]++;
        }
    }
}

int main()
{
	Prime();

	scanf("%lld %lld", &L, &R);

	find_prime();

	ull ans = 0;
	for (ll i = 0; i <= R - L; i++)
	{
		ull tt = 1;
		for (int j = 1; j <= pcnt[i]; j++)
		{
			ull t = 1, temp = 1;
			for (int k = 1; k <= ecnt[i][j]; k++)   // 等比数列求和
			{
				t *= num[i][j];
				temp += t;
			}
			tt *= temp;
		}
		ans += tt;
	}

	printf("%lld\n", ans);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/ummmmm/article/details/84137467
今日推荐