权值线段树
- 权值线段树维护的是桶,按值域开空间,维护的是个数。
- 简单线段树维护的是信息,按个数可开空间,维护的是特定信息。
普通线段树能解决区间最值和区间和问题
权值线段树可以解决数列第k大/小的问题
主席树能解决数列的子区间的第k大/小。
板子
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int tr[N * 4];
int n;
int a[N], b[N];
int s;
void change(int u, int l, int r, int x) // 单点修改
{
if (l == r)
{
tr[u]++;
return;
}
int mid = (l + r) / 2;
if (x <= mid)
change(u * 2, l, mid, x);
else
change(u * 2 + 1, mid + 1, r, x);
tr[u] = tr[u * 2 + 1] + tr[u * 2];
}
long long query(int u, int nl, int nr, int l, int r) // 区间查询
{
if (nl >= l && nr <= r)
return tr[u];
int res = 0;
int mid = (nr + nl) / 2;
if (l <= mid)
res += query(u * 2, nl, mid, l, r);
if (mid < r)
res += query(u * 2 + 1, mid + 1, nr, l, r);
return res;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + 1 + n); // 离散化
for (int i = 1; i <= n; i++)
{
int id = lower_bound(b + 1, b + 1 + n, a[i]) - b;
change(1, 1, n, id);
cout << query(1, 1, n, id + 1, n) << endl;
}
return 0;
}
/*
6
4 3 3 2 2 1
0
1
1
3
3
5*/
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18736436

浙公网安备 33010602011771号