给定一个由
n
n
n个数字组成的数组以及一个
x
x
x。现在从前往后遍历数组,若当前遍历的数字
a
[
i
]
a[i]
a[i]可以被
x
x
x整除,那么就在数组的最后加上
x
x
x个数字
a
[
i
]
x
\frac {a[i]}x
xa[i];若当前遍历的数字不能被
x
x
x整除,那么就停止遍历。
问题是当遍历完这个数组之后,数组中所有数字的总和
∑
i
=
1
n
a
[
i
]
\sum_{i=1}^na[i]
∑i=1na[i]等于多少。
首先要想明白的明白的是,假设数字
a
[
i
]
a[i]
a[i]可以被
x
x
x整除,那么整个数组所有数字的总和就会被加上
a
[
i
]
x
∗
x
\frac{a[i]}x * x
xa[i]∗x也就是
a
[
i
]
a[i]
a[i]这么多;对于被加到数组后面的
a
[
i
]
x
\frac{a[i]}x
xa[i],如果有一个
a
[
i
]
x
\frac{a[i]}x
xa[i]可以被再次遍历到,那么其他所有的
a
[
i
]
x
\frac{a[i]}x
xa[i]也都可以遍历到(原因很明显,他们是并排放进去的),若
a
[
i
]
x
\frac{a[i]}x
xa[i]还可以被
x
x
x整除,那么对于每个
a
[
i
]
x
\frac{a[i]}x
xa[i]都会在数组最后加上
x
x
x个
a
[
i
]
x
x
\frac{\frac{a[i]}x}x
xxa[i],那么一个
x
x
x个
a
[
i
]
x
\frac{a[i]}x
xa[i],所以数组所有数字总和一共加上了
x
∗
x
∗
a
[
i
]
x
x
x*x*\frac{\frac{a[i]}x}x
x∗x∗xxa[i]这么多,约分一下还是
a
[
i
]
a[i]
a[i]这么多。若继续下去会发现,每次都是加上了
a
[
i
]
a[i]
a[i]这么多。
现在假设这
n
n
n个数字,每个数字能被
x
x
x除的次数为
b
[
i
]
b[i]
b[i],那么在不考虑其他限制条件的情况下,每个数字能够对数组数字总和的额外贡献最多可以是
a
[
i
]
∗
b
[
i
]
a[i]*b[i]
a[i]∗b[i](根据上面的结论,一个数字被整除一次就可以多贡献
a
[
i
]
a[i]
a[i])。
但是实际上每个数字并不是都能贡献
b
[
i
]
b[i]
b[i]这么多次,原因在于:如果其中一个数字的
b
[
i
]
b[i]
b[i]太小了,比如特别极端的,
b
[
i
]
=
1
b[i]=1
b[i]=1的话,那么对于其他任何数字
a
[
j
]
a[j]
a[j]他们最多只能贡献两次,第一次是
a
[
j
]
a[j]
a[j]的时候,一次是
a
[
j
]
x
\frac{a[j]}x
xa[j]的时候(这一次不一定能够遍历到,需要满足
j
<
i
j<i
j<i,这里的
i
i
i是所有的最小的
b
[
i
]
b[i]
b[i]中最小的
i
i
i),因为当数组遍历到
a
[
i
]
x
\frac{a[i]}x
xa[i]的时候,这个数字不能再被
x
x
x整除,数组的遍历就会结束,那么对于后面的数字虽然
b
[
j
]
b[j]
b[j]可能会很大,但是数组不能够遍历到那里了,也就不会再有贡献了。
所以要取得所有数字中
b
[
i
]
b[i]
b[i]的最小值,这里设最小值为
b
m
i
n
b_{min}
bmin,这里的
m
i
n
min
min为出现最早的
m
i
n
min
min,即若
b
[
i
]
b[i]
b[i]的最小值为
1
1
1,有
b
[
2
]
=
1
,
b
[
3
]
=
1
b[2]=1, b[3]=1
b[2]=1,b[3]=1,那么就取
m
i
n
=
2
min=2
min=2,原因就是上面说到的,要求满足
j
<
i
j<i
j<i,
i
i
i是所有的最小的
b
[
i
]
b[i]
b[i]中最小的
i
i
i。
那么遍历完数组之后,整个数组数字之和
S
u
m
=
∑
i
=
1
m
i
n
−
1
a
[
i
]
∗
(
b
[
m
i
n
]
+
1
)
+
∑
i
=
m
i
n
n
a
[
i
]
∗
b
[
m
i
n
]
+
W
Sum=\sum_{i=1}^{min-1}a[i]*(b[min]+1)+\sum_{i=min}^na[i]*b[min]+W
Sum=∑i=1min−1a[i]∗(b[min]+1)+∑i=minna[i]∗b[min]+W,其中
W
W
W是在不遍历数组的时候,数组中所有数字的总和。
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int Maxn = 100005;
ll a[Maxn];
int b[Maxn];
void solve() {
memset(b, 0, sizeof b);
int n, minn = INF;
ll x, ans = 0;
scanf("%d %lld", &n, &x);
for (int i = 0; i < n; i++) {
scanf("%lld", a + i);
ans += a[i];
ll t = a[i];
while (t % x == 0) {
b[i]++;
t /= x;
}
minn = std::min(minn, b[i]);
}
bool flag = true;
for (int i = 0; i < n; i++) {
if (b[i] == 0) {
break;
}
if (b[i] == minn) {
flag = false;
}
if (flag) {
ans += (minn + 1) * a[i];
} else {
ans += minn * a[i];
}
}
printf("%lld\n", ans);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}