P10149 [Ynoi1999] XM66F 题解
比较好的莫队题。
思路
考虑使用莫队解决这个问题。
我们对于每个元素,统计 \(b_i=\sum_{j=1}^i [a_j<a_i]\)。
那么我们每一次新加入一个元素产生的贡献为 \(\sum_{j=l}^r [a_j=a_r](b_r-b_j)\)。
发现我们只需要统计 \(\sum_{j=l}^r [a_j=a_r]\) 与 \(\sum_{j=l}^r [a_j=a_r]b_j\)。
可以用桶简单维护。
时间复杂度 \(O(n\sqrt n)\)。
Code
#include <bits/stdc++.h>
using namespace std;
#define fro(i, x, y) for(int i = (x); i <= (y); i++)
#define pre(i, x, y) for(int i = (x); i >= (y); i--)
const int N = 5e5 + 10;
const int B = 800;
int n, m, a[N], t[N], b[N], pos[N];
long long num, t1[N], t2[N], ans[N];
struct Modui {
int l, r, id;
inline bool operator<(const Modui&t) const {
return pos[l] == pos[t.l] ? (pos[l] & 1 ? r < t.r : r > t.r) : l < t.l;
}
} d[N];
#define lb(x) (x&(-x))
inline void add(int x) { while(x <= n) t[x]++, x += lb(x); }
inline int ask(int x) { int r = 0; while(x) r += t[x], x -= lb(x); return r; }
inline void Add(int x) { num += abs(b[x] * t2[a[x]] - t1[a[x]]); t1[a[x]] += b[x], t2[a[x]]++; }
inline void Del(int x) { t1[a[x]] -= b[x], t2[a[x]]--; num -= abs(b[x] * t2[a[x]] - t1[a[x]]); }
signed main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
fro(i, 1, n) {
cin >> a[i];
}
fro(i, 1, n) {
pos[i] = (i - 1) / B + 1;
}
fro(i, 1, m) {
cin >> d[i].l >> d[i].r;
d[i].id = i;
}
sort(d + 1, d + m + 1);
fro(i, 1, n) {
b[i] = ask(a[i] - 1);
add(a[i]);
}
int l = 1, r = 0;
fro(i, 1, m) {
while(r < d[i].r) Add(++r);
while(l > d[i].l) Add(--l);
while(r > d[i].r) Del(r--);
while(l < d[i].l) Del(l++);
ans[d[i].id] = num;
}
fro(i, 1, m) cout << ans[i] << "\n";
return 0;
}
最后,感谢 @gxy001 的指导。