P1908 逆序对
P1908 逆序对
题目简述
求数列中逆序对个数
思路:
方法一:
利用树状数组,倒着来做(类似思想同P1168 中位数)
方法二:
利用归并排序,每次排序后可以利用其单调性性质直接算出答案(详细参考这个)
代码
方法一:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+5;
int a[N],b[N];
ll c[N];
int n;
int lowbit(int x){
return x&(-x);
}
void add(int x,int y){
for(int i=x;i<=n;i+=lowbit(i))c[i]+=y;
}
ll query(int x){
ll ans=0;
for(int i=x;i;i-=lowbit(i))ans+=c[i];
return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(a+1,a+1+n);
int tot=unique(a+1,a+1+n)-a-1;
for(int i=1;i<=n;i++)b[i]=lower_bound(a+1,a+1+tot,b[i])-a;
ll ans=0;
for(int i=n;i>=1;i--){
add(b[i],1);
ans+=query(b[i]-1);
}
cout<<ans<<endl;
return 0;
}
方法二:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+5;
int a[N],c[N];
ll ans;
int n;
void msort(int l,int r){
if(l==r)return ;
int mid=(l+r)>>1;
msort(l,mid);
msort(mid+1,r);
int b1=l,b2=mid+1;
int tmp=l;
while(b1<=mid&&b2<=r){
if(a[b1]>a[b2]){
ans+=mid-b1+1;
c[tmp++]=a[b2];
b2++;
}
else {
c[tmp++]=a[b1];
b1++;
}
}
while(b1<=mid){
c[tmp++]=a[b1];
b1++;
}
while(b2<=r){
c[tmp++]=a[b2];
b2++;
}
for(int i=l;i<=r;i++)a[i]=c[i];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
msort(1,n);
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号