題目思路
暫時無題目鏈接
問了一下其他隊過的思路,大概是這樣
別人的口胡
從小到大先把1移到它要去的地方然后再移2一直到n,但是不是直接移動
比如現在1的位置是5最終要到位置1,你就先區間查詢1-4位置的最小值,然后把1移到查詢的位置
然后這個區間的最小值移動到了5這個位置然后繼續查詢位置1到當前位置的最小值然后再往前移動
這樣次小的可以跟最小的再移動5 4 2 3 1先把1移動到3這個位置5 4 1 3 2你看看除了1往前走了
其他位置的值還是可以和原本一樣移動2選擇還可以更多處理完后你還可以將大的值再移動到最后
你這樣保證了移動前后其他位置的選擇不會減少你就看成處理完1 就把1這個位置去掉
因為1不能給貢獻了剩下的點選擇和之前一樣多
代碼
代碼還沒測驗過,不保證正確性
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=29;
const double eps=1e-6;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n;
int a[maxn],b[maxn];
int posa[maxn],posb[maxn];
void sw(int i,int j){
int tmpi=a[i];
int tmpj=a[j];
a[i]=tmpj;
a[j]=tmpi;
posa[a[i]]=i;
posa[a[j]]=j;
}
signed main(){
int _;scanf("%d",&_);
while(_--){
vector<pair<int,int> > ans;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
posa[a[i]]=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
posb[b[i]]=i;
}
bool flag=1;
for(int i=1;i<=n;i++){
if(posa[i]==posb[i]) continue;
if(posa[i]<posb[i]){
flag=0;
break;
}
int nowl=posb[i];
int nowr=posa[i];
for(int j=i+1;j<=n;j++){
if(posa[j]<=nowr&&posa[j]>=nowl){
ans.push_back({posa[j],nowr});
int tmp=posa[j];
sw(posa[j],nowr);
nowr=tmp;
}
}
}
for(int i=1;i<=n;i++){
if(a[i]!=b[i]){
flag=0;
}
}
if(!flag){
printf("-1\n");
}else{
printf("%d\n",ans.size());
for(auto x:ans){
printf("%d %d\n",x.fi,x.se);
}
}
}
return 0;
}