#include <bits/stdc++.h>
#define read(x) scanf("%d",&x)
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct node {
int h,idx;
bool operator < (const node &b) const {
if (h!=b.h) return h<b.h; //身高升序排列,求下标的逆序对
else return idx<b.idx;
}
}a[N];
int tr[N],w[N],n;//w数组存储每个位置的数的逆序对的个数
void update(int x,int c) {
for (int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
}
int query(int x) {
int res=0;
for (int i=x;i>=1;i-=lowbit(i)) res+=tr[i];
return res;
}
ll getSum(int n) {
return (ll)n*(n+1)/2;
}
int main()
{
read(n);
int h;
for (int i=1;i<=n;i++) read(h),a[i]={h,i};
//排序,
sort(a+1,a+n+1);
//去重
for (int i=2;i<=n;i++)
if (a[i].h==a[i-1].h) a[i].idx=a[i-1].idx;
//a[i]主动和谁换?求左边比a[i]大的
for (int i=1;i<=n;i++) {
update(a[i].idx,1);
w[i]=i-query(a[i].idx);
}
//a[i]被谁换?求右边比a[i]小的
memset(tr,0,sizeof tr);
for (int i=n;i>=1;i--) {
update(a[i].idx,1);
w[i]+=query(a[i].idx-1);
}
ll res=0;
for (int i=1;i<=n;i++) res+=getSum(w[i]);
printf("%lld",res);
return 0;
}
但只能过两组数据,第三组数据就错了,不知道错哪了。哪天再回来看吧。
输入数据。
100
42 701 893 20 333 520 919 446 482 203 126 707 527 814 528 598 369 165 449 3 377 539 301 638 912 970 810
102 149 983 713 410 472 89 382 785 142 824 73 141 199 825 317 679 219 597 548 67 343 467 566 580 924 337
859 939 482 618 8 746 598 926 124 753 230 271 132 308 881 171 727 294 49 921 375 3 780 504 389 251 117
609 359 720 487 70 632 632 355 617 719 589 482 771 118 7 655 422 63 757
出错区间:
52
482 203 126 707 527 814 528 598 369 165 449 3 377 539 301 638 912 970 810 102
149 983 713 410 472 89 382 785 142 824 73 141 199 825 317 679 219 597 548 67
343 467 566 580 924 337 859 939 482 618 8 746
2021.03.24
问题解决了,把第40、41行的去重去掉就好了。
结论:
离散化处理时,
- 如果求左边比它大的个数,右边比它小的个数:按h升序排列,如果h相同,则按idx升序排列。
- 如果求右边比它大的个数,左边比它小的个数:按h升序排列,如果h相同,则按idx降序排列。
不能去重,下标置相同。