Cod sursa(job #1241372)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 13 octombrie 2014 13:44:24
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
/// Craciun Catalin
///  Biperm2
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>

#define NMax 10005

using namespace std;

ifstream f("biperm.in");
ofstream g("biperm.out");

int n;
vector<int> Vec[NMax]; /// Vecini neorientat
bool vis[NMax];
int X[NMax], Y[NMax];
int compConexe = 0, len = 0;
/// Punctul B
vector<int> OVec[NMax]; /// Vecini orientat
int toRight = 0;
/// Punctul C
vector<pair<int, int> > toSwap;

inline int minim(int a, int b) { if (a<b) return a; return b; };
inline int maxim(int a, int b) { if (a>b) return a; return b; };

void dfsO(int k) {

    for (int i=0;i<Vec[k].size();i++) {
        int neighboor = Vec[k][i];

        bool ordered = false;
        for (int j=0;j<OVec[k].size();j++) {
            if (OVec[k][j] == neighboor)
                ordered = true;
        }

        Vec[k].erase(Vec[k].begin()+i);
        for (int j=0;j<Vec[neighboor].size();j++)
            if (Vec[neighboor][j] == k) {
                Vec[neighboor].erase(Vec[neighboor].begin() + j);
                break;
            }

        if (ordered) {
            toRight++;
        } else {
            toSwap.push_back(make_pair(minim(k, neighboor), maxim(k, neighboor)));
        }

        dfsO(neighboor);
    }
}

void dfs(int k) {

    len++;
    vis[k] = true;
    for (int i=0;i<Vec[k].size();i++) {
        if (!vis[Vec[k][i]]) {
            vis[Vec[k][i]] = true;
            dfs(Vec[k][i]);
        }
    }
}

bool shouldSwap(int x, int y) {

    if (x > y) {
        int aux = x;
        x = y;
        y = aux;
    }

    int left = 0, right = toSwap.size()-1;

    while (left <= right) {
        int mij = (left+right)/2;

        if (toSwap[mij].first == x && toSwap[mij].second == y) {
            toSwap.erase(toSwap.begin() + mij);
            return true;
        }

        if (toSwap[mij].first == x) {
            if (toSwap[mij].second > y) {
                right = mij - 1;
            } else {
                left = mij + 1;
            }
        } else if (toSwap[mij].first > x) {
            right = mij - 1;
        } else {
            left = mij + 1;
        }
    }

    return false;
/*
    for (int i=0;i<toSwap.size();i++) {
        if ((toSwap[i].first == x && toSwap[i].second == y) || (toSwap[i].first == y && toSwap[i].second == x)) {
            toSwap.erase(toSwap.begin() + i);
            return true;
        }
    }

    return false;*/
}

int main() {

    f>>n; memset(vis, false, sizeof(vis));
    for (int i=1;i<=n;i++)
        f>>X[i];
    for (int i=1;i<=n;i++)
        f>>Y[i];

    for (int i=1;i<=n;i++) {
        Vec[X[i]].push_back(Y[i]);
        Vec[Y[i]].push_back(X[i]);
        OVec[X[i]].push_back(Y[i]);
    }

    long long sum = 0;

    for (int i=1;i<=n;i++) {
        if (!vis[i]) {
            len = 0;
            dfs(i);
            toRight = 0;
            dfsO(i);
            sum+=minim(toRight, len-toRight);
            if (len > 1)
                compConexe++;
        }
    }

    g<<(long long)powl(2, compConexe)<<' '<<sum<<'\n';

    sort(toSwap.begin(), toSwap.end());

    for (int i=1;i<=n;i++) {
        if (shouldSwap(X[i], Y[i])) {
            int aux = X[i];
            X[i] = Y[i];
            Y[i] = aux;
        }
    }

    for (int i=1;i<n;i++) {
        g<<X[i]<<' ';
    }; g<<X[n]<<'\n';
    for (int i=1;i<n;i++) {
        g<<Y[i]<<' ';
    }; g<<Y[n]<<'\n';

    f.close();
    g.close();

    return 0;
}