[//]: # 细节:一定要深刻理解递归的顺序,递归是从底向上递归,注意tmp列表正如它的名字一样,在每次递归时都是暂时的,每次递归就清零。逆序对:当a[i]>a[j]时,那么i及其之后的左列表都与此时的j形成逆序对
方法:归并排序
题目描述
逆序对
def merge(a,l,r):
if l>=r:
return 0
mid=l+r>>1
res=merge(a,l,mid)+merge(a,mid+1,r)#递归左右两侧,且返回逆序对次数
i,j=l,mid+1
tmp=[]#每次递归tmp都清零,但是a列表是用遍历赋值,k-l,(l会随着递归而发生变化)而不是从0开始的,所以tmp需要在此定义为空
while i<=mid and j<=r:
if a[i]<=a[j]:
tmp.append(a[i])
i+=1
else:
tmp.append(a[j])
j+=1
res+=mid-i+1#左列表i之后的长度即为逆序对
while i<=mid:
tmp.append(a[i])
i+=1
while j<=r:
tmp.append(a[j])
j+=1
for k in range(l,r+1):#复制列表回原列表
a[k]=tmp[k-l]
return res
n=int(input())
q=[int(x) for x in input().split()]
print(merge(q,0,n-1))