#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();
| ~~~~~~~~^~
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Execution timed out |
1080 ms |
388 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Execution timed out |
1080 ms |
388 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |