Teee @ 2020-03-14 15:01:59
只有25分
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
using LL = long long;
const int N = 100005;
struct ST
{
int lc, rc;//左右子结点的编号
//这个点上是否有数
LL dat;
}tr[N];
int root, tot;
int build()
{
++tot;
tr[tot].lc = tr[tot].rc = tr[tot].dat = 0;
return tot;
}
//在val位置上的值加上delta,同时维护区间和
void insert(int p, int l, int r, int val)
{
if (l == r)
{
tr[p].dat = 1;
return;
}
int mid = l + r >> 1;
if (val <= mid)
{
if (!tr[p].lc) tr[p].lc = build();
insert(tr[p].lc, l, mid, val);
}
else
{
if (!tr[p].rc) tr[p].rc = build();
insert(tr[p].rc, mid + 1, r, val);
}
tr[p].dat = tr[tr[p].lc].dat + tr[tr[p].rc].dat;
}
//查询区间[L, R]
LL sum(int p, int l, int r, int L, int R)
{
if (L <= l && R >= r)
{
return tr[p].dat;
}
int mid = l + r >> 1;
LL res = 0;
if (mid >= L && tr[p].lc) res += sum(tr[p].lc, l, mid, L, R);
if (mid < R && tr[p].rc) res += sum(tr[p].rc, mid + 1, r, L, R);
return res;
}
int main()
{
//n个点
int n;
scanf("%d", &n);
//根节点
root = build();
LL res = 0;
int x;
for (int i = 1; i <= n; ++i)
{
scanf("%d", &x);
res += sum(1, 1, 1e9, x + 1, 1e9);
insert(1, 1, 1e9, x);
}
printf("%lld\n", res);
return 0;
}
by 万万没想到 @ 2020-03-14 15:11:30
insert函数的l==r不应该为累加而非赋值吗?
by Teee @ 2020-03-14 15:14:28
@万万没想到 l == r的确是赋值,我是在插入点赋值为1的
by 万万没想到 @ 2020-03-14 15:15:52
@Teee 但序列元素有可能重复啊。
by Teee @ 2020-03-14 15:19:30
@万万没想到 感谢