题目如下:
题解 or 思路
我们可以发现暴力去求解是无法完成的
O
(
n
2
)
O(n^2)
O(n2)
我们可以从贡献出发,计算每一个位置上的质因子所做的贡献
我们可以先通过分解质因子,记录每一个质因子的位置,在这里使用 v e c t o r vector vector 容器会使代码更加简洁方便。
先来一个例子:
3 2 3 3 3 2 2
第一个
2
2
2 的贡献是 2 * 6
第二个
2
2
2 的贡献是 4 * 2
我们可以发现每一个位置的贡献为
i
d
x
1
∗
(
n
−
i
d
x
1
+
1
)
idx_1 * (n - idx_1 + 1)
idx1∗(n−idx1+1)
i
d
x
1
idx_1
idx1为该质因子第一次出现的位置
(
i
d
x
i
−
i
d
x
i
−
1
)
∗
(
n
−
i
d
x
i
+
1
)
(idx_i - idx_{i - 1}) * (n - idx_i + 1)
(idxi−idxi−1)∗(n−idxi+1)
i
d
x
i
idx_i
idxi为非该质因子第一次出现的位置
将所有的贡献相加就是答案!
AC 代码:
#define ll long long
const int N = 1000009;
int n, s[N];
vector<int> g[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
int x; cin >> x;
for (int j = 2; j * j <= x; j++)
{
if (x % j == 0)
{
g[j].push_back(i);
while (x % j == 0)
x /= j;
}
}
if (x > 1)
g[x].push_back(i);
}
ll ans = 0;
for (int i = 2; i <= 1000000; i++)
{
if (g[i].size() == 0)
continue;
for (int j = 0; j < g[i].size(); j++)
{
if (j == 0)
ans += 1ll * g[i][j] * (n - g[i][j] + 1);
else
ans += 1ll * (g[i][j] - g[i][j - 1]) * (n - g[i][j] + 1);
}
}
cout << ans << '\n';
}
int main()
{
buff;
solve();
}