思路:
对于每个数的素因子的某个区间都会对答案有1的贡献,我们可以用类似埃式筛 来快速的求每个数的素因子,然后是每个素因子的区间个数,如果当前位置为i,则其覆盖的区间个数为i*(n-i+1),但如果出现过相同的素因子,则区间数为:(i-前一个相同素因子位置)*(n-i+1);;
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
const int N = 1e6 + 1000;
vector<int> p[N];
int a[N], b[N], pos[N], n;
long long ans;
void into()
{
b[0] = b[1] = 1;
for (int i = 2; i <= N; i++)
{
if (!b[i])
{
p[i].push_back(i);
for (int j = 2 * i; j <= N; j += i)
{
b[j] = 1;
p[j].push_back(i);
}
}
}
}
int main()
{
into();
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < p[a[i]].size(); j++)
{
int v = p[a[i]][j];
if (!pos[v])
ans += (long long)(n - i + 1) * i;
else
ans += (long long)(n - i + 1) * (i - pos[v]);
pos[v] = i;
}
}
cout << ans << endl;
return 0;
}