题目链接
F-命运的抉择_2024牛客寒假算法基础集训营6 (nowcoder.com)
题意
给一个长度为 \(n(2\le n\le 10^5)\) 的数组 \(a(1\le a_i\le 10^6)\),对每个 \(a_i\) 将其添加进数组 \(b\) 或数组 \(c\)。要求 \(b\) 和 \(c\) 均非空,两个数组中各任取一个元素 \(b_i,c_j\),均满足 \(\gcd(b_i,c_j)=1\)。
思路
先用筛法预处理出 \(10^6\) 范围内每个数的素因子。
然后采用并查集,如果两个数包含同一个素因子,那么它们就必须在同一个集合内。最终如果集合数小于 \(2\),则无解。对于可行解,可以将一个集合放入数组 \(b\),其余集合放入数组 \(c\)。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include<bits/stdc++.h>
#define endl '\n' #define debug(x) cout << #x << " = " << x << endl #define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << endl using namespace std;
typedef long long LL; typedef unsigned long long uLL; typedef pair<int, int> pii; const double eps = 1e-9; const int mod = 998244353; const int maxn = 1e5 + 10; const int maxa = 1e6;
int a[maxn], f[maxn]; bool vis[maxn]; vector<int> fac[1'000'001];
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
void solve() { int n; cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i]; f[i] = i; vis[i] = false; } map<int, int> mp; for(int i = 1; i <= n; i++) { for(auto x : fac[a[i]]) { if(mp.find(x) != mp.end()) { f[find(i)] = find(mp[x]); } else mp[x] = i; } }
int fir = 0, sec = 0; for(int i = 1; i <= n; i++) { int f = find(i); if(!vis[f]) { vis[f] = true; if(fir == 0) fir = f; else sec = f; } } if(!sec) cout << "-1 -1\n"; else { int lb = 0, lc = 0; for(int i = 1; i <= n; i++) { if(find(i) == fir) lb++; else lc++; } cout << lb << " " << lc << endl; for(int i = 1; i <= n; i++) { if(find(i) == fir) cout << a[i] << " "; } cout << endl; for(int i = 1; i <= n; i++) { if(find(i) != fir) cout << a[i] << " "; } cout << endl; } }
signed main() { cin.tie(nullptr)->sync_with_stdio(false); #ifdef sunset freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif
for(int i = 2; i <= maxa; i++) if(fac[i].empty()) for(int j = i; j <= maxa; j += i) fac[j].push_back(i);
int T = 1; cin >> T; while(T--) { solve(); } return 0; }
|