分析
刚开始看完全没办法下手,观察发现,可以计算出每一个位置的通过染色得到的最大值,设 f i f_i fi表示第i个位置最大值,那么只需要遍历一遍取最大值就可以了,重点是找出最大值后该怎么做,赛时观察出规律可能也可以过题,就是可以发现最后加起来的值对应从大到小的最大值,依次是 2 i 2^i 2i,也就是第一小的数加了1次,第二小的数加了2次,第三个加了4次…,其实对于 2 n − 1 2^n-1 2n−1种方式,会有一半方式得到最大值,因为存在小于最大值的数和最大值组合,然后在剩下的一半种,还会有一半是第二大的值,以此类推,就能得到每一个最大值的次数。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
const int mod = 998244353;
ll a[N];
void solve() {
int n;
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++) {
for(int j = i; j <= n; j += i) a[i] = max(a[i], a[j]);
}
sort(a + 1, a + 1 + n);
ll cnt = 1;
ll ans = 0;
for(int i = 1; i <= n; i ++) {
ans = (ans + a[i] * cnt % mod) % mod;
cnt = cnt * 2 % mod;
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1; //cin >> T;
while(T --) {
solve();
}
}