SGU180(树状数组,逆序对,离散)

时间:2023-03-10 00:27:10
SGU180(树状数组,逆序对,离散)

Inversions

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB
input: standard 
output: standard
There are N integers (1<=N<=65537) A1, A2,.. AN (0<=Ai<=10^9). You need to find amount of such pairs (i, j) that 1<=i<j<=N and A[i]>A[j].
Input
The first line of the input contains the number N. The second line contains N numbers A1...AN.
Output
Write amount of such pairs.
Sample test(s)
Input

2 3 1 5 4
Output
3

这道题需要离散,树状数组求逆序对是离散后,统计加入该元素时当前数组中

已经存在多少个比它大的数,这就是该数作为逆序对后者的贡献度,然后就可以

求解了,一般需要离散化。

 #include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
#define N 70007
using namespace std; int n;
long long ans;
int b[N],c[N];
struct Node
{
int zhi,id;
}a[N]; bool cmp(Node x,Node y)
{
return x.zhi<y.zhi;
}
int lowbit(int x)
{
return x&(-x);
}
void change(int x,int y)
{
for (int i=x;i<=n;i+=lowbit(i))
c[i]+=y;
}
int query(int x)
{
int res=;
for (int i=x;i>=;i-=lowbit(i))
res+=c[i];
return res;
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d",&a[i].zhi);
a[i].id=i;
}
sort(a+,a+n+,cmp);
int cnt=;
for (int i=;i<=n;i++)
{
if (a[i].zhi!=a[i-].zhi) b[a[i].id]=++cnt;
else b[a[i].id]=cnt;
}
for (int i=;i<=n;i++)
{
change(b[i],);
ans=ans+query(n)-query(b[i]);
}
printf("%lld",ans);
}