[拆分質因數] 求1e6區間內的數的因數之和 GYM 101652C
阿新 • • 發佈:2018-11-22
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; }