liuyuhanyyds @ 2021-11-03 18:27:46
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+7;
struct lyh
{
long long num,id;
}a[maxn];
long long n,ls[maxn],tree[maxn],ans=0;
bool cmp(lyh x,lyh y)
{
return x.num<y.num;
}
long long lowbit(long long x)
{
return x&(-x);
}
void updata(long long i,long long k)
{
while(i<=n)
{
tree[i]+=k;
i+=lowbit(i);
}
}
long long getsum(long long i)
{
long long res=0;
while(i>0)
{
res+=tree[i];
i-=lowbit(i);
}
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].num,a[i].id=i;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) ls[a[i].id]=i;
for(int i=1;i<=n;i++)
{
updata(ls[i],1);
ans+=(i-getsum(ls[i]));
}
cout<<ans;
return 0;
}
by loris @ 2021-11-03 18:32:56
你这做法也是够奇葩
by loris @ 2021-11-03 18:35:03
树状数组求逆序对不需要排序
求逆序对,就是求在对于没个i,a[1~i-1]中比a[i]大的数的个数的总和。
显然一个简单的处理方法就是每次让b[a[i]]+1,然后找b[1~i-1]的和就代表在a[1~i-1]中比a[i]小的数的个数,一减就可以得到比a[i]大的个数。
这个过程就可以用树状数组维护。
by xixike @ 2021-11-03 18:46:31
@loris 树状数组求逆序对排序不是很正常吗?排序之后插入查询离散化之后的排名也很好理解吧
by xixike @ 2021-11-03 19:10:29
@liuyuhanyyds 你排序之后再给ls
数组赋值其实相当于对原数组离散化(意思就是没排序)。
问题出在排序上,直接sort
是不稳定的,意思是两个相等的数排序之后可能会交换位置,而在这道题中交换位置会有影响,所以sort
要这么写:
if(x.num != y.num) return x.num < y.num;
return x.id < y.id;
by xixike @ 2021-11-03 19:11:08
是 cmp
里,打错了/kk。
by loris @ 2021-11-03 19:25:53
@xixike 啊我之前一直都是离散化但不排序啊又学到了新做法
by liuyuhanyyds @ 2021-11-04 18:16:15
@xixike 谢谢神犇,已经改好了