1311:【例2.5】求逆序对
时间限制: 1000 ms 内存限制: 65536 KB
提交数:65263 通过数: 15596
【题目描述】
给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目。
【输入】
第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。
【输出】
所有逆序对总数。
【输入样例】
4
3
2
3
2
【输出样例】
3
【提示】
N≤105,Ai≤105
本题理解:
暴力是不可能AC其他逆序对的题目的!!!!
本题其实可以用暴力
本题正解可以在归并的基础上加亿点骚操作即可!!;
#include<bits/stdc++.h>
using namespace std;
int a[500005],o[500005],n;long long sum;
void q(int l,int r){
if(l>=r)return;
int m=(l+r)>>1;//有点难理解,其实就是所有二进制位右移一位,实质等同于m=(l+r)/2。
int i=l,j=m+1,k=l;
q(l,m);
q(m+1,r);
while(i<=m && j<=r){
if(a[i]<=a[j])o[k++]=a[i++];
else o[k++]=a[j++],sum+=m-i+1;//重点1:上面的if可以在排序的同时,完成判断是否逆序
}
while(i<=m)o[k++]=a[i++];
while(j<=r)o[k++]=a[j++];//这里不需要,因为不满足条件,i<j但a[i]<a[j];
for(int t=l;t<=r;t++)a[t]=o[t];//重点2:排序的基础,为后面的判断创造套件
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
q(1,n);
cout<<sum;
return 0;
}