제출 #241067

#제출 시각아이디문제언어결과실행 시간메모리
241067osaaateiasavtnlRailway Trip (JOI17_railway_trip)C++14
30 / 100
2083 ms11376 KiB
#include<bits/stdc++.h> using namespace std; #define ii pair <int, int> #define app push_back #define all(a) a.begin(), a.end() #define bp __builtin_popcountll #define ll long long #define mp make_pair #define f first #define s second #define Time (double)clock()/CLOCKS_PER_SEC const int N = 1e5+7, INF = 1e9+7; int n, k, q; int a[N], ans[N]; int pref[N], suff[N]; int newl[N], newr[N]; vector <int> pos[N]; int par[N]; int root(int u) { if (par[u] == u) return u; else return par[u] = root(par[u]); } void merge(int u, int v) { u = root(u); v = root(v); if (u != v) { par[u] = v; } } int link_l[N], link_r[N]; signed main() { #ifdef HOME freopen("input.txt", "r", stdin); #else #define endl '\n' ios_base::sync_with_stdio(0); cin.tie(0); #endif cin >> n >> k >> q; for (int i = 1; i <= n; ++i) cin >> a[i]; vector <ii> d; for (int i = 0; i < q; ++i) { int u, v; cin >> u >> v; if (v < u) swap(u, v); d.app(mp(u, v)); ans[i] = INF; } for (int i = 1; i <= k; ++i) pos[i].app(0); for (int i = 1; i <= n; ++i) pos[a[i]].app(i); for (int i = 1; i <= k; ++i) pos[i].app(n+1); for (int i = 1; i <= n; ++i) par[i] = i; auto same_dist = [&](int i, int j) { int p1 = lower_bound(all(pos[a[i]]), i) - pos[a[i]].begin(); int p2 = lower_bound(all(pos[a[j]]), j) - pos[a[j]].begin(); return abs(p1-p2); }; for (int x = 1; x <= k; ++x) { //cout << "x " << x << endl; for (int i : pos[x]) { if (i && a[i - 1] <= x) { merge(i, i - 1); } if (i + 1 <= n && a[i + 1] <= x) { merge(i, i + 1); } } memset(link_l, 0, sizeof link_l); memset(link_r, 0, sizeof link_r); for (int i = 1; i <= n; ++i) newl[i] = newr[i] = INF; for (int i : pos[x]) { link_l[i] = link_r[i] = i; newl[i] = newr[i] = 0; for (int j = i - 1; j; --j) { if (a[j] >= a[i]) break; newr[j] = suff[j]+1; link_r[j] = i; } for (int j = i + 1; j <= n; ++j) { if (a[j] >= a[i]) break; newl[j] = pref[j]+1; link_l[j] = i; } } for (int i = 1; i <= n; ++i) { newl[i] = min(newl[i], newr[i]+1); newr[i] = min(newr[i], newl[i]+1); } //pref - dist to nearest prefix maximum //suff - dist to nearest suffix maximum //newl - dist to nearest left x //newr - dist to nearest right x //link_l = number of the nearest left x int lf = 0; for (int i = 1; i <= n; ++i) { if (a[i] > x) { lf = i; continue; } auto t = upper_bound(all(pos[x]), lf); if (*t <= i) { auto link = prev(upper_bound(all(pos[x]), i)); pref[i] = newl[i] + (link - t); } else if (link_r[i]) { pref[i] = min(pref[i], newr[i]); } } int rf = n+1; for (int i = n; i; --i) { if (a[i] > x) { rf = i; continue; } auto t = prev(upper_bound(all(pos[x]), rf)); if (*t >= i) { auto link = lower_bound(all(pos[x]), i); suff[i] = newr[i] + (t - link); } else if (link_l[i]) { suff[i] = min(suff[i], newl[i]); } } for (int i = 0; i < q; ++i) { int u = d[i].f, v = d[i].s; if (root(u) == root(v)) { if (link_l[u] && link_l[v]) { ans[i] = min(ans[i], newl[u] + newl[v] + same_dist(link_l[u], link_l[v])); } if (link_l[u] && link_r[v]) { ans[i] = min(ans[i], newl[u] + newr[v] + same_dist(link_l[u], link_r[v])); } if (link_r[u] && link_l[v]) { ans[i] = min(ans[i], newr[u] + newl[v] + same_dist(link_r[u], link_l[v])); } if (link_r[u] && link_r[v]) { ans[i] = min(ans[i], newr[u] + newr[v] + same_dist(link_r[u], link_r[v])); } } } } for (int i = 0; i < q; ++i) cout << ans[i] - 1 << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...