树状数组RE代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int n;
int a[N];
int tr0[N];
struct Node
{
int l, r, max;
} tr[N * 4];
void pushup(int u)
{
tr[u].max = max(tr[u << 1].max, tr[u << 1 | 1].max);
}
void build(int u, int l, int r)
{
tr[u] = {l, r, 0};
if (l == r)
{
tr[u].max = l;
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int x, int d)
{
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if (l == r)
{
tr[u].max = d;
return;
}
if (x <= mid)
modify(u << 1, x, d);
else
modify(u << 1 | 1, x, d);
pushup(u);
}
int query(int u, int x, int y)
{
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if (x <= l && r <= y)
return tr[u].max;
int res = 0;
if (x <= mid)
res = max(res, query(u << 1, x, y));
if (y > mid)
res = max(res, query(u << 1 | 1, x, y));
return res;
}
int lowbit(int x)
{
return x & -x;
}
int add(int x, int d)
{
for (int i = x; i <= n; i += lowbit(i))
tr0[i] += d;
}
int find(int x)
{
int res = 0;
for (int i = x; i; i -= lowbit(i))
res += tr0[i];
return res;
}
int main()
{
scanf("%d", &n);
build(1, 1, n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = n; i; i--)
{
a[i] = query(1, 1, a[i]);
if (!a[i])
{
printf("-1\n");
return 0;
}
modify(1, a[i], 0);
}
// for (int i = 1; i <= n; i++)
// printf("%d ", a[i]);
// puts("");
LL ans = 0;
for (int i = 1; i <= n; i++)
{
add(a[i], 1);
ans += find(n) - find(a[i]);
}
printf("%lld\n", ans);
return 0;
}
线段树AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int n;
int a[N];
int tr0[N];
struct Node
{
int l, r, tag;
} tr1[N * 4], tr2[N * 4];
void pushup(Node tr[], int u, int type)
{
if (!type)
tr[u].tag = max(tr[u << 1].tag, tr[u << 1 | 1].tag);
else
tr[u].tag = tr[u << 1].tag + tr[u << 1 | 1].tag;
}
void build(Node tr[], int u, int l, int r, int type)
{
tr[u] = {l, r, 0};
if (l == r)
{
if (!type)
tr[u].tag = l;
return;
}
int mid = l + r >> 1;
build(tr, u << 1, l, mid, type), build(tr, u << 1 | 1, mid + 1, r, type);
pushup(tr, u, type);
}
void modify(Node tr[], int u, int x, int d, int type)
{
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if (l == r)
{
if (!type)
tr[u].tag = d;
else
tr[u].tag += d;
return;
}
if (x <= mid)
modify(tr, u << 1, x, d, type);
else
modify(tr, u << 1 | 1, x, d, type);
pushup(tr, u, type);
}
int query(Node tr[], int u, int x, int y, int type)
{
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if (x <= l && r <= y)
return tr[u].tag;
int res = 0;
if (x <= mid)
if (!type)
res = max(res, query(tr, u << 1, x, y, type));
else
res += query(tr, u << 1, x, y, type);
if (y > mid)
if (!type)
res = max(res, query(tr, u << 1 | 1, x, y, type));
else
res += query(tr, u << 1 | 1, x, y, type);
return res;
}
int main()
{
scanf("%d", &n);
build(tr1, 1, 1, n, 0);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = n; i; i--)
{
a[i] = query(tr1, 1, 1, a[i], 0);
if (!a[i])
{
printf("-1\n");
return 0;
}
modify(tr1, 1, a[i], 0, 0);
}
LL ans = 0;
build(tr2, 1, 1, n, 1);
for (int i = 1; i <= n; i++)
{
modify(tr2, 1, a[i], 1, 1);
ans += query(tr2, 1, 1, n, 1) - query(tr2, 1, 1, a[i], 1);
}
printf("%lld\n", ans);
return 0;
}
不同点就在于确定好顺序后求逆序对的那一部分