Time Limit: 3000/1000MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others)
Chika
说希望和我一起做学园偶像的时候,我真的很开心。——WatanabeYou
曜是千歌的青梅竹马,但是Aqours成立以后,千歌似乎总是与梨子在一起,而把曜冷落了。
为了让千歌知晓自己的心意,曜酱决定做一件大事!她决定把一个给定的1~n的排列{a1,a2,…,an}(1≤ai≤n,且ai各不相同),用最少的交换次数,变换成另一个1~n的排列{b1,b2,…,bn}。并且,每次只交换相邻的两个元素。
也许这样做了以后,千歌能更多地注意自己吧。曜这样想。
Input
第一行是一个整数n,第二行是一个长度为n的1~n的排列a,
第三行是另一个长度为n的1~n的排列b。
Output
输出一行,一个整数,表示最少的交换次数。
样例输入1:
4
2 3 1 4
3 2 1 4
样例输出1:
1
样例输入2
3
3 2 1
1 2 3
样例输出3:
3
Hint
1≤n≤100000
题解:
13年NOIP的题目,仔细想想就会发现是一个求逆序对,就是b数组为重新定义的数字大小顺序,然后求问a数组中用这种顺序定义的逆序对有几对。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#define INF 1999122700
#define LiangJiaJun main
using namespace std;
int n;
long long ans=0;
struct data{
int a,b;
}ev[100004];
int a[100004],b[100004],rv[100004];
int tr[100004];
inline int lowbit(int x){return x&(-x);}
void add(int x,int val){
for(int i=x;i<=n;i+=lowbit(i))tr[i] += val;
}
int query(int x){
int res=0;
for(int i=x;i;i-=lowbit(i))res += tr[i];
return res;
}
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
rv[b[i]]=i;
}
for(int i=1;i<=n;i++){
ev[i].b=rv[a[i]];
ev[i].a=a[i];
}
for(int i=1;i<=n;i++){
ans += ((long long)i - query(ev[i].b)-1);
add(ev[i].b,1);
}
cout<<ans<<endl;
return 0;
}