逆序对问题的升级版本(不知道的童鞋自行百度BIT/线段树求逆序对)
本体思路以三个数中间的数为基准,找前面比他大得数有几个
后面比他小的数有几个(可以算出来)
然后相乘+到res里即可
#include <bits/stdc++.h>
using namespace std;
#define N (int)1e5+10
int arr[N];
#define lc root<<1
#define rc root<<1|1
typedef long long ll;
struct seg{
int l, r;
ll he, lazy, tag;
}t[4*N];
void build(int root, int l, int r)
{
t[root].l = l, t[root].r = r;
t[root].lazy = 0;
t[root].tag = -1;
if (l == r)
{
t[root].he = 0;
return;
}
int m = (l + r) >> 1;
build(lc, l, m);
build(rc, m+1, r);
t[root].he = t[lc].he + t[rc].he;
}
void imptag(int root, ll change)
{
t[root].tag = change;
t[root].he = (t[root].r - t[root].l + 1) * change;
t[root].lazy = 0;
}
void implazy(int root, ll change)
{
t[root].lazy += change;
t[root].he += (t[root].r - t[root].l + 1) * change;
}
void pushdown(int root)
{
ll temp1 = t[root].tag;
if (temp1 != -1)
{
imptag(lc, temp1);
imptag(rc, temp1);
t[root].tag = -1;
}
ll temp2 = t[root].lazy;
if (temp2)
{
implazy(lc, temp2);
implazy(rc, temp2);
t[root].lazy = 0;
}
}
void assignment(int root, int l, int r, ll change)
{
if (r < t[root].l || l > t[root].r) return;
if (l <= t[root].l && t[root].r <= r)
{
imptag(root, change);
return;
}
pushdown(root);
assignment(rc, l, r, change);
assignment(lc, l, r, change);
t[root].he = t[lc].he + t[rc].he;
}
void update(int root, int l, int r, ll change)
{
if (r < t[root].l || l > t[root].r) return;
if (l <= t[root].l && t[root].r <= r)
{
implazy(root, change);
return;
}
pushdown(root);
update(rc, l, r, change);
update(lc, l, r, change);
t[root].he = t[lc].he + t[rc].he;
}
ll query(int root, int l, int r)
{
if (r < t[root].l || l > t[root].r) return 0;
if (l <= t[root].l && t[root].r <= r)
{
return t[root].he;
}
pushdown(root);
return query(rc, l, r) + query(lc, l, r);
}
int main(void)
{
int n;
ll res = 0; int i;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &arr[i]);
}
build(1, 1, n);
update(1, arr[1], arr[1], 1);
for (i = 2; i <= n; i++)
{
ll temp1 = query(1, arr[i]+1, n);
ll temp2 = arr[i]-1 - (i-1-temp1);
res += temp1 * temp2;
update(1, arr[i], arr[i], 1);
}
cout << res;
}
线段树部分为带lazy和tag的模板,大家可以复制一下用。。。