AGC010E
[多校联合集训24]排列游戏
题意
Hellen首先按照自己的意愿将n个数重新排列(可以是原来的顺序),然后她让Shawn进行如下操作:选择一对相邻且互质的数,交换它们的位置.(这个操作Shawn可以进行无数次.)
Hellen想要这个序列的字典序尽可能小,而Shawn想要这个序列的字典序尽可能大.Hellen想让你告诉她在两人都采取最优策略的情况下,最后形成的序列是什么样子的.
题解
AGC010E
我们如果把 \(a\) 和 \(b\) 满足 \(\gcd(a,b) \not =1\) 那么就连一条边(因为 \(a\) 和 \(b\) 的相对位置无法改变),我们要做的就是要定向这个图(最小定向),然后最大化他的拓扑排序。
我们考虑定向这玩意直接贪心就行了,首先从一个没遍历过的最小点开始,然后编号从小到大的访问没访问过的点即可。然后用一个堆维护当前入度为0的节点,每次取出来堆顶的元素更新即可。
#include <bits/stdc++.h>
const int mod = 998244353, N = 2e3 + 5, INF = 0x3f3f3f3f;
const double eps = 1e-9;
template<typename T>inline T read() { T x = 0; bool f = 0; char ch = getchar(); while (!isdigit(ch)) { f = ch == '-'; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); } return f ? -x : x; }
template<typename T>inline T max(const T &x, const T &y) { return x > y ? x : y; }
template<typename T>inline T min(const T &x, const T &y) { return x < y ? x : y; }
template<typename T>inline T abs(const T &x) { return x > 0 ? x : -x; }
inline int Mod(int x) { if (x >= mod) { return x - mod; } else if (x < 0) { return x + mod; } else { return x; } }
template<typename T1, typename T2>
struct pair {
T1 first;
T2 second;
pair(const T1 &x = 0, const T2 &y = 0) { first = x; second = y; }
friend pair operator + (const pair<T1, T2> &x, const pair<T1, T2> &y) { return pair(x.first + y.first, x.second + y.second); }
friend pair operator - (const pair<T1, T2> &x, const pair<T1, T2> &y) { return pair(x.first - y.first, x.second - y.second); }
friend bool operator < (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first < y.first || (x.first == y.first && x.second < y.second); }
friend bool operator <= (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first < y.first || (x.first == y.first && x.second <= y.second); }
friend bool operator > (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first > y.first || (x.first == y.first && x.second > y.second); }
friend bool operator >= (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first > y.first || (x.first == y.first && x.second >= y.second); }
friend bool operator == (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first == y.first && x.second == y.second; }
friend bool operator != (const pair<T1, T2> &x, const pair<T1, T2> &y) { return x.first != y.first || x.second != y.second; }
};
template<typename T1, typename T2>
inline pair<T1, T2> make_pair(const T1 &x, const T2 &y) { return pair<T1, T2>(x, y); }
template<typename T>
struct stack { int top; T vals[N]; bool empty() { return !top; } void push(T x) { vals[++top] = x; } void pop() { if (top > 0) { --top; } return; } void clear() { top = 0; } T TOP() { return top ? vals[top] : T(-1); } };
inline int ksm(int x, int y) { int ret = 1; for ( ; y; y /= 2, x = 1LL * x * x % mod) { if (y & 1) { ret = 1LL * ret * x % mod; } } return ret; }
inline int ksc(int x, int y) { int ret = 0; for ( ; y; y /= 2, x = Mod(x + x)) { if (y & 1) { ret = Mod(ret + x); } } return ret; }
struct graph { int cnt, h[N]; pair<int, int> edge[N * 2]; void add_edge(int x, int y) { edge[cnt].first = y; edge[cnt].second = h[x]; h[x] = cnt++; } void clear() { memset(h, -1, sizeof h); cnt = 0; } };
inline int ls(int k) { return k << 1; }
inline int rs(int k) { return k << 1 | 1; }
inline int sign(double x) { if (abs(x) < eps) { return 0; } else if (x < 0) { return -1; } else { return 1; } }
using std::set;
using std::map;
using std::vector;
using std::ios;
using std::cin;
using std::cout;
using std::endl;
using std::queue;
using std::cerr;
#define orz_1
#define orz_2
int n, a[N], d[N], vis[N];
vector<int> e[N], t[N];
void dfs(int u) {
vis[u] = 1;
for (auto &j: e[u]) {
if (!vis[j]) {
t[u].push_back(j);
dfs(j);
}
}
}
int main() {
#ifndef siriehn_nx
freopen("arrange.in", "r", stdin);
freopen("arrange.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout << std::fixed << std::setprecision(10);
#endif
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
std::sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; ++i) {
for (int j = i + 1; j <= n; ++j) {
if (std::__gcd(a[i], a[j]) != 1) {
e[i].push_back(j);
e[j].push_back(i);
}
}
}
std::priority_queue<int> q;
for (int i = 1; i <= n; ++i) {
if (!vis[i]) {
dfs(i);
q.push(i);
}
}
for ( ; q.size(); ) {
int nw = q.top();
q.pop();
cout << a[nw] << ' ';
for (auto &j: t[nw]) {
q.push(j);
}
}
cout << '\n';
#ifdef siriehn_nx
cerr << "The time of this EXE is " << (((double) clock()) / CLOCKS_PER_SEC) << "s\n";
#endif
return 0;
}