[板子]线段树求逆序对
作者:互联网
RT,板子题不会像题解一样细讲,只是记录一下,以防考试板子打错
这棵线段树是一棵权值线段树!
#include <bits/stdc++.h>
using namespace std;
const int N = 500000;
typedef long long LL;
int n;
int m;
LL ans;
int a[N + 30];
int b[N + 30];
struct ST
{
int l, r;
LL sum;
}t[N * 8 + 30];
int read()
{
int s = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar();
}
return s * f;
}
inline void built(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (l == r)
return ;
int mid = (l + r)>>1;
built(p<<1, l, mid);
built(p<<1|1, mid + 1, r);
}
inline void change(int p, int s)
{
if (t[p].l == s && t[p].r == s)
{
++t[p].sum;
return ;
}
int mid =(t[p].l + t[p].r)>>1;
if (s <= mid)
change(p<<1, s);
else
change(p<<1|1, s);
t[p].sum = t[p<<1].sum + t[p<<1|1].sum;
}
LL ask(int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r)
return t[p].sum;
LL tot = 0;
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid)
tot += ask(p<<1, l, r);
if (mid < r)
tot += ask(p<<1|1, l, r);
return tot;
}
int main()
{
n = read();
for (int i = 1; i <= n; ++i)
{
a[i] = read();
b[i] = a[i];
}
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b;
for (int i = 1; i <= n; ++i)
a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
built(1, 1, n);
for (int i = 1; i <= n; ++i)
{
change(1, a[i]);
ans += i - ask(1, 1, a[i]);
}
printf ("%lld\n", ans);
return 0;
}
标签:ch,int,线段,30,板子,树求,LL,逆序 来源: https://www.cnblogs.com/martixx/p/13553485.html