Submission #1021349

#TimeUsernameProblemLanguageResultExecution timeMemory
1021349huutuanSorting (IOI15_sorting)C++14
100 / 100
885 ms118928 KiB
#include "sorting.h" #include <bits/stdc++.h> using namespace std; struct DSU{ int cnt; vector<int> lab; vector<pair<int*, int>> changes; void init(int n){ cnt=0; lab.assign(n, -1); } int find_set(int u){ return lab[u]<0?u:find_set(lab[u]); } void union_sets(int u, int v){ u=find_set(u); v=find_set(v); if (u!=v){ if (lab[u]>lab[v]) swap(u, v); changes.emplace_back(&lab[u], lab[u]); changes.emplace_back(&lab[v], lab[v]); lab[u]+=lab[v]; lab[v]=u; changes.emplace_back(&cnt, cnt); ++cnt; } } void rollback(int size){ while ((int)changes.size()>size){ *changes.back().first=changes.back().second; changes.pop_back(); } } } dsu; struct SegmentTree{ int n; vector<vector<pair<int, int>>> t; void init(int _n){ n=_n; t.assign(4*n+1, {}); } void update(int k, int l, int r, int L, int R, int u, int v){ if (r<L || R<l) return; if (L<=l && r<=R){ t[k].emplace_back(u, v); return; } int mid=(l+r)>>1; update(k<<1, l, mid, L, R, u, v); update(k<<1|1, mid+1, r, L, R, u, v); } int dfs(int k, int l, int r){ int size=dsu.changes.size(); for (auto &i:t[k]) dsu.union_sets(i.first, i.second); int ans=-1; if (l==r){ if (dsu.cnt<=l) ans=l; }else{ int mid=(l+r)>>1; if (ans==-1) ans=dfs(k<<1, l, mid); if (ans==-1) ans=dfs(k<<1|1, mid+1, r); } dsu.rollback(size); return ans; } } st; int a[200010], s[200010], pos[200010], pa[200010]; int mp[200010]; int findSwapPairs(int N, int S[], int M, int X[], int Y[], int P[], int Q[]) { M=min(M, N+10); dsu.init(N); st.init(M+1); for (int i=0; i<N; ++i) s[i]=S[i], a[i]=i, mp[s[i]]=0, pa[i]=i; for (int i=0; i<M; ++i){ if (X[i]!=Y[i]){ int p1=pa[X[i]], p2=pa[Y[i]]; st.update(1, 0, M, mp[s[p1]], i, s[p1], a[p1]); st.update(1, 0, M, mp[s[p2]], i, s[p2], a[p2]); swap(a[p1], a[p2]); pa[a[p1]]=p1; pa[a[p2]]=p2; mp[s[p1]]=i+1; mp[s[p2]]=i+1; } } for (int i=0; i<N; ++i) st.update(1, 0, M, mp[s[i]], M, s[i], a[i]); int ans=st.dfs(1, 0, M); if (ans==-1) return -1; for (int i=0; i<N; ++i) s[i]=S[i], a[i]=i, pos[s[i]]=i; for (int i=ans-1; i>=0; --i) swap(a[X[i]], a[Y[i]]); set<int> f; for (int i=0; i<N; ++i) if (a[i]!=s[i]) f.insert(i); for (int i=0; i<ans; ++i){ P[i]=Q[i]=0; swap(a[X[i]], a[Y[i]]); swap(s[X[i]], s[Y[i]]); pos[s[X[i]]]=X[i]; pos[s[Y[i]]]=Y[i]; f.erase(X[i]); f.erase(Y[i]); if (a[X[i]]!=s[X[i]]) f.insert(X[i]); if (a[Y[i]]!=s[Y[i]]) f.insert(Y[i]); if (f.size()){ int j=*f.begin(); f.erase(f.begin()); int k=pos[a[j]]; P[i]=j, Q[i]=k; } swap(s[P[i]], s[Q[i]]); pos[s[P[i]]]=P[i]; pos[s[Q[i]]]=Q[i]; f.erase(P[i]); f.erase(Q[i]); if (a[P[i]]!=s[P[i]]) f.insert(P[i]); if (a[Q[i]]!=s[Q[i]]) f.insert(Q[i]); } if (is_sorted(s, s+N)) return ans; return -1; }

Compilation message (stderr)

sorting.cpp: In member function 'int SegmentTree::dfs(int, int, int)':
sorting.cpp:56:32: warning: conversion from 'std::vector<std::pair<int*, int> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   56 |       int size=dsu.changes.size();
      |                ~~~~~~~~~~~~~~~~^~
#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...