CF1876 B 题解
题意:
你有一个长为 \(n\) 的序列 \(a(1\le n\le 10^5)\)。现在你可以在序列中可重地选若干个下标,这个位置和下标的倍数的位置也会被选。获得的价值是选出的位置上数的最大值,不能不选。你显然有 \(2^n-1\) 种选法,现在请你求出这些选法的价值总和,模 \(998244353\)。
思路:
我们并不关心一个位置上的数是什么,而应关心选了这个数后被选的数中最大的,这部分我们显然可以暴力扫一遍预处理出来,复杂度是 \(\sum_{i-1}^n\frac{n}{i}=O(n\log n)\)。
现在我们来考虑元素之间的贡献,考虑选了一个数,这次选择的价值由它来贡献当且仅当选了之后大于它的数一个都没有被选,而小于等于它的是可以随便选的。因此我们对预处理出来的结果排个序,设排序后的数组为 \(b\)。则答案 \(res=\sum_{i-1}^nb_i*2^{i-1}\) 算一下发现刚好 \(2^n-1\) 是正确的。
扫一遍是 \(O(n)\) 排序是 \(O(n\log n)\)。总体就是 \(O(n\log n)\) 的。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 998244353;
int t, n, a[100005], mx[100005];
signed main(){
ios::sync_with_stdio(false);
cin >> n; int res = 0;
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) mx[i] = max(mx[i], a[j]);
sort(mx + 1, mx + n + 1);
for(int i = 1, bas = 1; i <= n; i++, bas = bas * 2 % mod)
res = (res + bas * mx[i]) % mod;
cout<< res << '\n';
}

浙公网安备 33010602011771号