题解:AT_abc276_f [ABC276F] Double Chance

· · 题解

思路

根据题意,对于第 K 次询问,答案为:

\dfrac{\sum\limits_{i=1}^K\sum\limits_{j=1}^K \max(A_i, A_j)}{K^2} 当我们从 $K-1$ 个元素扩展到 $K$ 个元素,加入新元素 $A_i$ 时,新增的 $\max$ 和由三部分组成: - 前面小于等于 $A_i$ 的数 $y$,取 $\max$ 显然为 $A_i$。 - 前面大于 $A_i$ 的数 $y$,取 $\max$ 显然为 $y$。 - 当前两次都取 $A_i$,取 $\max$ 为 $A_i$。 所有小于 $A_i$ 的数的总贡献为小于 $A_i$ 的个数乘 $A_i$ 再乘 $2$($A_i$ 可以和小于 $A_i$ 的数顺序调换,所以乘 $2$)。 所有大于 $A_i$ 的数的总贡献为大于 $A_i$ 的数的总和乘 $2$(同理)。 最后再加上 $A_i$,这是两次都取到 $A_i$ 的贡献。 注意到 $1 \le A_i \le 2 \times 10^5$,值域区间求个数和区间和,可以用两个权值树状数组分别维护。 ## Code ```cpp #include <bits/stdc++.h> #define int long long using namespace std; namespace Creeper{ const int N = 2e5 + 5, mod = 998244353; int n, a[N], ans; struct Tree{ int t[N]; int lowbit(int x) {return x & (-x);} void modify(int x, int y) {while (x < N) {t[x] += y; x += lowbit(x);}} int qry(int x) {int res = 0; while (x) {res += t[x]; x -= lowbit(x);} return res;} }A, B; int qp(int a, int b, int p) { int res = 1; while (b) { if (b & 1) res *= a; res %= p; a *= a; a %= p; b >>= 1; } return res; } void solve() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; ans += (2 * A.qry(a[i]) % mod + 1) * a[i] % mod + ((B.qry(200000) % mod - B.qry(a[i]) % mod) % mod + mod) % mod * 2 % mod; ans %= mod; cout << ans * qp(i * i % mod, mod - 2, mod) % mod << '\n'; A.modify(a[i], 1); B.modify(a[i], a[i]); } } } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int T = 1; // cin >> T; while (T--) Creeper::solve(); } ```