Submission #1154344

#TimeUsernameProblemLanguageResultExecution timeMemory
1154344cpismylifeOwOSirni (COCI17_sirni)C++20
98 / 140
1753 ms851968 KiB
#include <bits/stdc++.h> using namespace std; const int inf = 1e7 + 1; const long long mod = 1e9 + 7; const int MaxN = 1e5 + 5; const int MaxA = 1e7 + 5; int n; int arr[MaxN]; void Inp() { cin >> n; for (int x = 1; x <= n; x++) { cin >> arr[x]; } sort(arr + 1, arr + n + 1); } int parents[MaxN]; int sz[MaxN]; pair<int, int> cur[MaxN]; int FindSet(int p) { if (parents[p] == p) { return p; } parents[p] = FindSet(parents[p]); return parents[p]; } bool UnionSet(int a, int b) { a = FindSet(a); b = FindSet(b); if (a == b) { return false; } if (sz[a] < sz[b]) { swap(a, b); } parents[b] = a; sz[a] += sz[b]; return true; } int pre[MaxA]; int dis[MaxA]; pair<int, int> now[MaxN]; vector<int> pr[MaxN]; vector<pair<int, int>> cntsrt[MaxA]; bool mark[MaxN]; void Exc() { int mxa = 0; for (int x = 1; x <= n; x++) { parents[x] = x; sz[x] = 1; mxa = max(mxa, arr[x]); } int cnt = 0; for (int x = 1; x <= n; x++) { int y = x; while (y <= n && arr[x] == arr[y]) { UnionSet(x, y); mark[y] = false; y++; } y--; mark[y] = true; pre[arr[x]] = y; cnt++; x = y; } for (int x = mxa; x > 0; x--) { dis[x] = 0; if (!pre[x]) { pre[x] = pre[x + 1]; dis[x] = dis[x + 1] + 1; } } for (int x = 1; x <= n; x++) { if (!mark[x]) { continue; } if (arr[x] < mxa && dis[arr[x] + 1] + 1 < arr[x]) { int p = pre[arr[x] + 1]; pr[x].push_back(p); pr[p].push_back(x); } for (int y = arr[x] + arr[x]; y <= mxa; y += arr[x]) { int q = dis[y], p = pre[y]; if (q < arr[x]) { pr[x].push_back(p); pr[p].push_back(x); } else { y += ((q / arr[x]) - 1) * arr[x]; } } } for (int x = 1; x <= n; x++) { for (int y : pr[x]) { int k = min(arr[x] % arr[y], arr[y] % arr[x]); cntsrt[k].push_back(make_pair(y, x)); } pr[x].clear(); } for (int x = mxa; x >= 0; x--) { for (int y = 0; y < (int)cntsrt[x].size(); y++) { int id = cntsrt[x][y].second; pr[id].push_back(cntsrt[x][y].first); } cntsrt[x].clear(); } long long res = 0; while (cnt > 1) { for (int x = 1; x <= n; x++) { now[x] = cur[x] = make_pair(inf, 0); } for (int x = 1; x <= n; x++) { if (!mark[x]) { continue; } while (!pr[x].empty() && FindSet(pr[x].back()) == FindSet(x)) { pr[x].pop_back(); } if (!pr[x].empty()) { int id = pr[x].back(); now[x] = min(now[x], make_pair(min(arr[x] % arr[id], arr[id] % arr[x]), id)); } } for (int x = 1; x <= n; x++) { cur[FindSet(x)] = min(cur[FindSet(x)], now[x]); } for (int x = 1; x <= n; x++) { if (parents[x] == x && UnionSet(x, cur[x].second)) { res += cur[x].first; cnt--; } } } cout << res; } int main() { //freopen("A.INP", "r", stdin); //freopen("A.OUT", "w", stdout); ios_base::sync_with_stdio(false); cin.tie(nullptr); int test = 1; //cin >> test; for (int x = 1; x <= test; x++) { Inp(); Exc(); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...