幻化
晚上chipizz同学突然问我这道题,然后我口胡了一下先把
a
a
数组的位变成
i
i
然后再把改成对应映射再求逆序数
然而第一个样例就不对・(PД`q。)・゜・
emmm,事实上是自己思路有问题, i,j i , j 位置的数字交换不等效与一位一位 swap s w a p 过去.
对于
i,j
i
,
j
两个位置的数字交换后,单个数而言的最小
cost=|i−j|2
c
o
s
t
=
|
i
−
j
|
2
,这一点很容易想到,但事实上大部分数不是一步到位的,这里我们假设
di
d
i
是
ai
a
i
到
i
i
的距离,设
实际上,每一次
i
i
到中必定存在一个
posx<=i
p
o
s
x
<=
i
,我们每次交换
ai和posx的数字x,然后再从pos=x的位置交换到ai位置
a
i
和
p
o
s
x
的
数
字
x
,
然
后
再
从
p
o
s
=
x
的
位
置
交
换
到
a
i
位
置
便可得到最优解,
实际上也不用考虑这么麻烦,我们可以想象一下每一次交换之后
ans
a
n
s
都在减小,说明每一次交换并不会增加我们要的
cost
c
o
s
t
.
结合之前的部分正确想法,我们可以得到
convai=i
c
o
n
v
a
i
=
i
那么实际上的
cost=12∑ni=1|i−convbi|
c
o
s
t
=
1
2
∑
i
=
1
n
|
i
−
c
o
n
v
b
i
|
代码就很简单啦
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<limits.h>
#include<string.h>
#include<map>
#include<list>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define eps double(1e-6)
#define pi acos(-1.0)
#define lson root << 1
#define rson root << 1 | 1
int a[200005];
int b[200005];
int conv[200005];
int n;
int main()
{
int zu;
scanf("%d",&zu);
while(zu--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),conv[a[i]]=i;
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
ll ans=0;
for(int i=1;i<=n;i++)
ans+=abs(i-conv[b[i]]);
printf("%lld\n",ans/2);
}
}