Submission #1265614

#TimeUsernameProblemLanguageResultExecution timeMemory
1265614nguyenhuythachSirni (COCI17_sirni)C++20
140 / 140
2901 ms756864 KiB
#include<bits/stdc++.h> #include <algorithm> #include <random> #include <chrono> #include <cstdlib> #include <ctime> #include <numeric> #include <vector> #include <stack> #include <map> #include <set> #include <queue> #include <iomanip> using namespace std; #define ll long long #define L LLONG_MAX #define fi first #define se second #define pii pair<int,int> #define sz(a) ((int)a.size()) #define FOR(i,j,k) for(int i=j;i<=k;i++) #define REP(i,k,j) for(int i=k;i>=j;i--) #define FORD(i,a) for(auto i:a) #define rngdcl mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()) #define random(l,r) ((l)+(rng()%(r-l+1))) struct triple { int u,v,w; }; bool operator < (triple a,triple b) { return a.w<b.w; } const int nmax=1e5+1; const int pmax=1e7+1; int n,mx=0; vector<pii> p; vector<triple> edge; bool cnt[pmax]; void input() { cin >> n; FOR(i,1,n) { int x; cin >> x; if(!cnt[x]) p.push_back({x,i}); cnt[x]=true; mx=max(mx,x); } } struct DSU { vector<int> par; DSU() {} void init(int n) { par.resize(n+5,0); FOR(i,1,n) par[i]=i; } int find(int v) { if(v==par[v]) return v; return par[v]=find(par[v]); } bool joint(int u,int v) { u=find(u); v=find(v); if(u!=v) { par[v]=u; return true; } return false; } }; DSU dsu; // Counting sort for edges by weight (minimal extra memory: vector<int> freq of size maxw+1) void counting_sort_edges(vector<triple>& a, int maxw) { if(a.empty()) return; int K = maxw + 1; vector<int> freq(K); for(auto &e: a) ++freq[e.w]; for(int i=1;i<K;i++) freq[i]+=freq[i-1]; vector<triple> b(a.size()); for(int i=(int)a.size()-1;i>=0;--i) { int w = a[i].w; int pos = --freq[w]; b[pos] = a[i]; } a.swap(b); // b freed when function exits } void solve() { dsu.init(n); sort(p.begin(),p.end()); FORD(i,p) { long long cur = (long long)i.fi + 1; while (cur <= mx) { auto it = lower_bound(p.begin(), p.end(), pair<int,int>((int)cur, 0)); if (it == p.end()) break; if (it->se == i.se) { ++it; if (it == p.end()) break; } edge.push_back({ i.se, (*it).se, (*it).fi % i.fi }); long long k = (long long)(*it).fi / i.fi; cur = (k + 1) * 1LL * i.fi; } } // use counting sort instead of std::sort to avoid TLE int maxw = 0; for(auto &e: edge) if(e.w > maxw) maxw = e.w; counting_sort_edges(edge, maxw); int ans=0; FORD(i,edge) ans+=dsu.joint(i.u,i.v)*i.w; cout << ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); input(); solve(); }
#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...