Loading

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 的指导。

posted @ 2024-02-15 22:10  JiaY19  阅读(19)  评论(0编辑  收藏  举报