zoukankan      html  css  js  c++  java
  • arc111c

    arc111c

    大意

    略。。

    思路

    乱搞竟然过了(

    首先,可以确定不成立的情况,当且仅当存在 (k) ,使 (a_kleq 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;
    }
    
  • 相关阅读:
    0505.Net基础班第十四天(winform基础)
    0505.Net基础班第十三天(面向对象多态)
    Z-index
    div的padding和margin
    隐藏div,文本框角圆滑,消除外边框
    页面加载完成之后运行方法里的内容,隐藏标签,判断字符串里面是否包含某个字符
    CSS命令
    漂浮
    电子时钟
    用二维数组存数据(学科成绩、总分以及平均值)
  • 原文地址:https://www.cnblogs.com/ullio/p/14559303.html
Copyright © 2011-2022 走看看