CF1876B Tutorial
Aleph_Drawer · · 题解
首先,直接按照题目中所描述的方法进行统计的时间复杂度明显难以承受。此时一个比较基础经典却非常有效的技巧是:改变统计方式,改成对于每一个数计算它对答案的贡献。
考虑一个数
这启示我们先对
那么
时间复杂度是
我的代码写的比较烂。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5 + 105, MOD = 998244353;
ll n, a[N], p2[N], cnt, ans;
bool tag[N];
ll rng[N];
bool cmp(ll x, ll y) {
return a[x] > a[y];
}
int main() {
scanf("%lld", &n);
p2[0] = 1;
for(ll i = 1; i <= n; i++)
scanf("%lld", &a[i]), p2[i] = p2[i - 1] * 2ll % MOD, rng[i] = i;
stable_sort(rng + 1, rng + n + 1, cmp);
ll cnt = 0, tmp = 0; // cnt := |S|, tmp := |T|
for(ll i = 1; i <= n; i++) {
ll pos = rng[i];
if(tag[pos])
continue;
for(ll j = 1; j * j <= pos; j++) {
if(!(pos % j)) {
if(!tag[j]) {
tmp++;
tag[j] = 1;
}
if(!tag[pos / j]) {
tmp++;
tag[pos / j] = 1;
}
}
}
ans += (p2[n - cnt] - p2[n - cnt - tmp]) * a[pos] % MOD;
cnt += tmp;
tmp = 0;
ans %= MOD;
}
printf("%lld\n", (ans % MOD + MOD) % MOD);
return 0;
}