#include using namespace std; const int N = 500010; typedef long long LL; LL ans; int n; //每个输入的数字,我们关心两个方面:1、数值 2、位置(序号) struct Node { int val; int id; } d[N]; bool operator<(const Node &a, const Node &b) { if (a.val == b.val) return a.id > b.id; //两个数一样大,序号大的靠前,这样统计出来的正序对才正确 return a.val > b.val; //数不一样大,数大的靠前 } //下面是树状数组模板 int t[N]; //返回非负整数x在二进制表示下最低位1及其后面的0构成的数值 int lowbit(int x) { return x & -x; } //将序列中第x个数加上k void add(int x, int k) { for (int i = x; i <= n; i += lowbit(i)) t[i] += k; } //查询序列前x个数的和 int sum(int x) { int sum = 0; for (int i = x; i; i -= lowbit(i)) sum += t[i]; return sum; } int main() { scanf("%d", &n); //读入每个数,分别将数值、序号记录到结构体数组d中 for (int i = 1; i <= n; i++) { scanf("%d", &d[i].val); d[i].id = i; } //对结构体数组进行排序,大的在前,小的在后;如果数值一样,序号大的在前,小的在后 sort(d + 1, d + 1 + n); //逆序对的定义:id[j] // d数组是由大到小排完序的,按由大到小的顺序动态维护树状数组,计算每次变化后出现的i