题目
https://vjudge.net/problem/Gym-101981J
题意
定义:mul (l, r) = (∏_{i=l}^r) (a_i)
fac (l, r) 为 mul (l, r) 的所有不同的质因子的个数
求 (∑_{i = 1}^n)(∑_{j = i}^n)fac (i, j)
题解
根据题目要求可以列出要求的内容
(a_1)
(a_1)*(a_2) (a_2)
(a_1)*(a_2)*(a_3) (a_2)*(a_3) (a_3)
…… …… ……
(a_1)*(a_2)*……*(a_n) (a_2)*(a_3)*……*(a_n) (a_n)
要求的也就是上面这些个数的不同质因子个数之和,观察一下可以发现第 1 行到第 2 行就是将 2 项 (a_2) 加入结果,而对于答案的影响也就是新加入的 (a_2) 的质因子,由此可知第 i 行到第 i + 1 行对于答案的影响就是 (a_i) 的质因子 * i。那么我们记录下每个质因子最后是在第几层加入的,那么就知道原数中已经有几个数包含了这个质因子,那么新加入的质因子对于答案的贡献也就是 i - 该质因子之前的层数。
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define met(a, b) memset(a, b, sizeof(a)) 5 #define rep(i, a, b) for(int i = a; i <= b; i++) 6 #define bep(i, a, b) for(int i = a; i >= b; i--) 7 #define lowbit(x) (x&(-x)) 8 #define MID (l + r) / 2 9 #define ls pos*2 10 #define rs pos*2+1 11 #define pb push_back 12 #define ios() ios::sync_with_stdio(0) 13 14 using namespace std; 15 16 const int maxn = 1e6 + 1010; 17 const int inf = 0x3f3f3f3f; 18 const ll INF = 0x3f3f3f3f3f3f3f3f; 19 const ll mod = 123456789; 20 21 bitset<maxn> is_prime; 22 int prime[maxn], prime_cnt; 23 ll vis[maxn]; 24 ll res, now; 25 26 void get_prime(int n) { 27 is_prime[1] = 1; 28 rep(i, 2, n) { 29 if(!is_prime[i]) prime[++prime_cnt] = i; 30 for(int j = 1; j <= prime_cnt && i * prime[j] <= n; j++) { 31 is_prime[i * prime[j]] = 1; 32 if(i % prime[j] == 0) break; 33 } 34 } 35 } 36 ll calc(ll n, ll x) { 37 ll sum = 0; 38 for(int i = 1; i <= prime_cnt && is_prime[n] && prime[i] <= n; i++) { 39 while(n % prime[i] == 0) { 40 sum += x - vis[prime[i]]; 41 vis[prime[i]] = x; 42 n /= prime[i]; 43 } 44 } 45 if(!is_prime[n]) { 46 sum += x - vis[n]; 47 vis[n] = x; 48 } 49 return sum; 50 } 51 52 int main() { 53 ios(); 54 get_prime(maxn - 1); 55 int n; 56 cin >> n; 57 rep(i, 1, n) { 58 ll a; 59 cin >> a; 60 now += calc(a, i); 61 res += now; 62 } 63 cout << res << endl; 64 return 0; 65 }