AtCoder Regular Contest 116 B - Products of Min-Max(排列组合)
Problem Statement
Given is a sequence A of N integers. There are 2N−1 non-empty subsequences B of A. Find the sum of max(B)×min(B) over all of them.
Since the answer can be enormous, report it modulo 998244353.
Constraints
- All values in input are integers.
- 1≤N≤2×105
- 0≤Ai≤998244352
和2021牛客寒假训练赛某题很类似。暴力肯定不可做,考虑枚举贡献。首先对序列排序,朴素的想法是枚举最大值a[j]和最小值a[i],乘起来再乘以以此为最大值最小值的序列个数(即\(2^{j - i - 1}\)),注意如果j == i 或者j == i + 1的话个数只有一个。这样也是会t的。不妨进一步考虑,只枚举最大值,然后乘以一个类似前缀和的东西,比如枚举到的最大值是a[4],那么此时答案要加上的就是\(a[4]\times(a[1]\times2^2+a[2]\times2^1+a[3]\times2^0+a[4]\times2^0)\),如果枚举到的是a[5],则为\(a[5]\times(a[1]\times2^3+a[2]\times2^2+a[3]\times2^1+a[4]\times2^0+a[5]\times2^0)\)。不难发现规律:不妨设i = 4时类前缀和tmp为\(a[1]\times2^2+a[2]\times2^1+a[3]\times2^0\),当i = 5时tmp先变为2倍,然后再加上\(a[i - 1]\times2^0\),此时令\(ans += tmp + a[i]\times a[i]\)即可。注意特判i = 1,2,3的情况。
#include <iostream>
#define mod 998244353
using namespace std;
int n;
long long a[2000005], ans = 0;
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
long long tmp = 0;
for(int i = 1; i <= n; i++) {
if(i == 1) {
tmp = a[1];
ans += a[1] * a[1] % mod;
} else if(i == 2) {
tmp = (a[1] + a[2]) % mod;
ans = (ans + tmp * a[2] % mod) % mod;
} else if(i == 3) {
tmp = (2 * a[1] % mod + a[2] % mod) % mod;
ans = (ans + tmp * a[3] % mod) % mod;
ans = (ans + a[3] * a[3] % mod) % mod;
} else {
tmp = tmp * 2 % mod;
tmp = (tmp + a[i - 1]) % mod;
ans = (ans + tmp * a[i] % mod) % mod;
ans = (ans + a[i] * a[i] % mod) % mod;
}
}
cout << ans;
return 0;
}