arc111c
arc111c
大意
略。。
思路
乱搞竟然过了(
首先,可以确定不成立的情况,当且仅当存在 \(k\) ,使 \(a_k\leq b_{p_k}\)
我们按 \(a_i\) 从大到小考虑。
不妨设当前未匹配的位置 \(a_i\) 的最大值在第 \(r\) 位,那么,我们交换 \(p_r\) 和 \(p_{p_r}\)
相当于让 \(p_r\) 回到第 \(p_r\) 位上。
如果某一次交换时 \(r == p_r\) ,那么我们找到当前还未归位的 \(a_i\) 最大的位置,重复上面的操作。
我按 \(a_i\) 排序后用链表维护当前还未归位的序列,每次从末尾向前跳一步就能找到当前还未归位的最大值。
当然,常数比较大...
代码
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 1e9+7;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int n;
int a[200200], b[200200], p[200200];
struct node {
int id, val;
void init(cint x, cint y) {
id = x; val = y;
}
bool operator < (const node&a) const {
return val < a.val;
}
} s[200200];
int idt[200200];
int ans[200200][2], cnt;
int nx[200200], la[200200];
void cut(cint loc) {
la[nx[loc]] = la[loc];
nx[la[loc]] = nx[loc];
}
void NO() {
cout << -1 << endl;
exit(0);
}
int main() {
bool flag = 0;
cin >> n;
for(int i=1; i<=n; i++) {cin >> a[i];}
for(int i=1; i<=n; i++) {cin >> b[i];}
for(int i=1; i<=n; i++) {cin >> p[i];}
for(int i=1; i<=n; i++) {if(a[i] <= b[p[i]] && i != p[i]) flag = 1;}
if(flag) NO();
for(int i=1; i<=n; i++) s[i].init(i, a[i]);
sort(s+1, s+1+n);
for(int i=1; i<=n; i++) idt[s[i].id] = i;
nx[0] = 1; la[n+1] = n;
for(int i=1; i<=n; i++) nx[i] = i+1, la[i] = i-1;
while(la[n+1] != 0) {
flag = 1;
int r = la[n+1];
if(p[s[r].id] == s[r].id) cut(r);
else {
// cout << "r : " << r << endl << s[r].id << ' ' << s[r].val << endl;
int my = p[s[r].id];
cut(idt[my]);
ans[++cnt][0] = s[r].id;
ans[cnt][1] = my;
swap(p[s[r].id], p[my]);
if(p[my] == s[r].id) cut(r);
}
}
cout << cnt << endl;
for(int i=1; i<=cnt; i++)
cout << ans[i][0] << ' ' << ans[i][1] << endl;
return 0;
}