답안 #778257

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
778257 2023-07-10T07:54:20 Z boris_mihov 정렬하기 (IOI15_sorting) C++17
36 / 100
1000 ms 468 KB
#include "sorting.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <stack>

typedef long long llong;
const int MAXN = 200000 + 10;
const int INF  = 1e9;

int n;
int p[MAXN];
struct CompDSU
{
    struct Node
    {
        int prev;
        int next;
        int comp;
    };

    int cnt;
    Node list[MAXN];

    CompDSU()
    {
        cnt = 0;
    }

    void assignNewComp(int node)
    {
        cnt++;
        if (p[node] == node)
        {
            list[node].prev = list[node].next = node;
            list[node].comp = cnt; 
            return;
        }

        list[node].comp = cnt;
        list[node].next = p[node];
        list[p[node]].prev = node;
        int curr = p[node];

        while (curr != node)
        {
            list[curr].next = p[curr];
            list[p[curr]].prev = curr;
            list[curr].comp = cnt;
            curr = p[curr];
        }
    }

    void disconnect(int u, int v)
    {
        int nextNode = u;
        int prevNode = u;

        while (nextNode != v && prevNode != v)
        {
            // std::cout << "here: " << nextNode << ' ' << prevNode << ' ' << u << ' ' << v << '\n';
            nextNode = list[nextNode].next;
            prevNode = list[prevNode].prev;
        }

        int prevU = list[u].prev;
        int nextU = list[u].next;
        int prevV = list[v].prev;
        int nextV = list[v].next;

        std::swap(list[nextU].prev, list[nextV].prev);
        std::swap(p[u], p[v]);
        std::swap(list[u], list[v]);
        list[u].next = p[u];
        list[u].prev = prevU;
        list[v].next = p[v];
        list[v].prev = prevV;

        if (nextNode == v)
        {
            assignNewComp(u);
        } else
        {
            assignNewComp(v);
        }
    }

    void connect(int u, int v)
    {
        cnt -= 2;
        int prevU = list[u].prev;
        int nextU = list[u].next;
        int prevV = list[v].prev;
        int nextV = list[v].next;

        std::swap(list[nextU].prev, list[nextV].prev);
        std::swap(p[u], p[v]);
        std::swap(list[u], list[v]);
        list[u].next = p[u];
        list[u].prev = prevU;
        list[v].next = p[v];
        list[v].prev = prevV;

        assignNewComp(u);
    }

    void print()
    {
        std::cout << "cycle status\n";
        for (int i = 1 ; i <= n ; ++i)
        {
            std::cout << i << ": " << list[i].comp << ' ' << list[i].next << ' ' << list[i].prev << '\n';
        }
    }

    bool areConnected(int u, int v)
    {
        return list[u].comp == list[v].comp;
    }
};

CompDSU dsu;
int pos[MAXN];
bool vis[MAXN];
std::vector <std::pair <int,int>> ops;
std::stack <std::pair <int,int>> st;

void getOps()
{
    ops.clear();
    std::fill(vis + 1, vis + 1 + n, false);
    for (int i = 1 ; i <= n ; ++i)
    {
        if (vis[i])
        {
            continue;
        }

        while (!st.empty())
        {
            st.pop();
        }

        int curr = i;
        while (!vis[curr])
        {
            vis[curr] = true;
            curr = p[curr];
        
            if (!vis[curr])
            {
                st.push({p[curr], p[i]});
            }
        }

        while (!st.empty())
        {
            ops.push_back(st.top());
            st.pop();
        }
    }
}

void makeSwap(int x, int y)
{
    std::swap(p[x], p[y]);
    pos[p[x]] = x;
    pos[p[y]] = y;
}

std::vector <int> avaliable;
int findSwapPairs(int N, int S[], int M, int X[], int Y[], int P[], int Q[]) 
{
    n = N;
    for (int i = 1 ; i <= n ; ++i)
    {
        p[i] = S[i - 1] + 1;
    }

    for (int i = 1 ; i <= n ; ++i)
    {
        if (dsu.list[i].comp == 0)
        {
            dsu.assignNewComp(i);
        }
    }

    fflush(stdout);
    getOps();
    if (ops.empty())
    {
        return 0;
    }

    for (int i = 1 ; i <= M ; ++i)
    {
        int u = X[i - 1] + 1;
        int v = Y[i - 1] + 1;
        if (!dsu.areConnected(u, v))
        {
            dsu.connect(u, v);
            avaliable.push_back(i - 1);
            continue;
        }

        if (u != v) dsu.disconnect(u, v);
        avaliable.push_back(i - 1);
        if (n - dsu.cnt <= avaliable.size())
        {
            getOps();
            while (ops.size() < i)
            {
                ops.push_back({1, 1});
            }

            break;
        }
    }
    
    for (int i = 1 ; i <= n ; ++i)
    {
        p[i] = S[i - 1] + 1;
        pos[p[i]] = i;
    }

    for (int i = 0 ; i < ops.size() ; ++i)
    {
        makeSwap(X[i] + 1, Y[i] + 1);
        P[avaliable[i]] = pos[ops[i].first] - 1;
        Q[avaliable[i]] = pos[ops[i].second] - 1;
        makeSwap(P[i] + 1, Q[i] + 1);
    }

    for (int i = 1 ; i <= n ; ++i)
    {
        assert(p[i] == i);
    }

    return ops.size();
}

Compilation message

sorting.cpp: In function 'int findSwapPairs(int, int*, int, int*, int*, int*, int*)':
sorting.cpp:210:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  210 |         if (n - dsu.cnt <= avaliable.size())
      |             ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
sorting.cpp:213:31: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  213 |             while (ops.size() < i)
      |                    ~~~~~~~~~~~^~~
sorting.cpp:228:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  228 |     for (int i = 0 ; i < ops.size() ; ++i)
      |                      ~~^~~~~~~~~~~~
sorting.cpp:241:20: warning: conversion from 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
  241 |     return ops.size();
      |            ~~~~~~~~^~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 320 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 320 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 340 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 1 ms 212 KB Output is correct
10 Correct 1 ms 340 KB Output is correct
11 Correct 1 ms 340 KB Output is correct
12 Correct 0 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 320 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 340 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 1 ms 212 KB Output is correct
10 Correct 1 ms 340 KB Output is correct
11 Correct 1 ms 340 KB Output is correct
12 Correct 0 ms 340 KB Output is correct
13 Correct 0 ms 212 KB Output is correct
14 Correct 1 ms 212 KB Output is correct
15 Correct 1 ms 340 KB Output is correct
16 Correct 1 ms 340 KB Output is correct
17 Correct 1 ms 340 KB Output is correct
18 Correct 1 ms 212 KB Output is correct
19 Correct 0 ms 212 KB Output is correct
20 Correct 0 ms 324 KB Output is correct
21 Execution timed out 1090 ms 468 KB Time limit exceeded
22 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1080 ms 388 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1080 ms 388 KB Time limit exceeded
2 Halted 0 ms 0 KB -