火柴排队(映射排序)

题目

分析:

想要和最小,需要差值的平方最小

那么,所有序列从大到小一一对应是最小的,即:a中第一小对应b中第一小,a中第二小对应b中第二小,依次往后

实现上述想法,需要离散化,即用a的相对位置(a序列不变)去给b排序

此时需要映射排序

先给a和b相对位置进行排序,排列如下

把原序列的数值按从小到大排序,并记住他们原来的下标

(为什么要先把a,b数组这样排序呢?我的想法是:可以快速找到a中第小的数,b中第1小的数,每次可以同时操作,a中第小的数和b中第1小的数,并把它们关系表示出来

比如:下边的例子,可以直接找到a,b中第1,2,3,4小的值,并把它们映射c[2]=2,c[1]=0,c[0]=3,c[3]=1)

5 3 2 8
3 8 2 5


[(2, 2), (3, 1), (5, 0), (8, 3)]
[(2, 2), (3, 0), (5, 3), (8, 1)]

然后用c数组,表示映射关系

c[a1[i][1]]=b1[i][1]

表示a中第1小的数,在a数组中的第2个位置,b中第1小的数,在b数组中的第2个位置,

表示a中第2小的数,在a数组中的第1个位置,b中第2小的数,在b数组中的第0个位置,

...

然乎就可以表示用c数组表示他们的相对关系

最后只需要求出c中的逆序对个数(树状数组求),即为答案


mod=99999997
n = int(input())
tr=[0]*(n+10)
c=[0]*(n+10)
a=list(map(int,input().split()))
b=list(map(int,input().split()))

a1=[]
b1=[]

def lowbit(x):
    return x&(-x)
def query(x):
    res=0
    while x>0:
        res+=tr[x]
        x-=lowbit(x)
    return res
def add(x,k):
    while x<n+5:
        tr[x]+=k
        x+=lowbit(x)
        
for i in range(0,n):
    a1.append((a[i],i))
    b1.append((b[i],i))

a1.sort(key=lambda item:(item[0]))
b1.sort(key=lambda item:(item[0]))
print(a1)
print(b1)
#print(a1)
for i in range(0,n):
    c[a1[i][1]]=b1[i][1]

res=0
for i in range(n-1,-1,-1):
    res=(res+query(c[i]+1))%mod #因为是前缀和,所以c的所有设置要全部加1
    add(c[i]+1,1)
print(res)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值