Submission #1114738

#TimeUsernameProblemLanguageResultExecution timeMemory
1114738ShaShiPalembang Bridges (APIO15_bridge)C++17
31 / 100
131 ms114876 KiB
#include <bits/stdc++.h> #define int long long // #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") // #pragma GCC optimize("O3") // #pragma GCC optimize("unroll-loops") #define F first #define S second #define mp make_pair #define pb push_back #define all(x) x.begin(), x.end() #define kill(x) cout << x << "\n", exit(0); #define pii pair<int, int> #define pll pair<long long, long long> #define endl "\n" using namespace std; typedef long long ll; // typedef __int128_t lll; typedef long double ld; const int MAXN = (int)1e6 + 7; const int MOD = 998244353; const ll INF = (ll)1e18 + 7; int n, m, k, tmp, t, tmp2, tmp3, tmp4, u, v, w, flag, q, ans, N, res, pre_ans; pii arr[MAXN], di[MAXN]; char ch, ch2; vector<int> vec[2][MAXN], cmp; int ps[2][MAXN]; vector<int> cnt[2][MAXN]; inline int id(int n) { return lower_bound(all(cmp), n)-cmp.begin(); } vector<pii> _vec; map<int, int> _cnt; inline int solve1() { for (int i=1; i<=n; i++) { u = arr[i].F; v = arr[i].S; _cnt[u]++, _cnt[v]++, _vec.pb({u, v}), tmp2 += 2; } int res2 = 0; for (auto cur: _cnt) { tmp += cur.S; // cout << cur.F << " " << cur.S << endl; if (tmp+tmp >= tmp2) { tmp = cur.F; break; } } for (auto cur:_cnt) res2 += abs(cur.F-tmp)*cur.S; tmp = tmp2 = 0; return res2+_vec.size(); } /* Segment Tree */ #define mid ((l+r)>>1) #define lid (id<<1) #define rid (lid|1) struct D { int sigmaL, sigmaR, cnt; D () {} } seg[MAXN<<2], emp; inline D merge(D x, D y) { D res; res.sigmaL = x.sigmaL+y.sigmaL; res.sigmaR = x.sigmaR+y.sigmaR; res.cnt = x.cnt+y.cnt; return res; } void add(int s, int ind, int l=0, int r=N, int id=1) { // if (id == 1) cout << "+ " << arr[ind].F << " " << arr[ind].S << " " << s << endl; if (l+1 == r) { seg[id].cnt++; seg[id].sigmaL += arr[ind].F; seg[id].sigmaR += arr[ind].S; return; } if (s < mid) add(s, ind, l, mid, lid); else add(s, ind, mid, r, rid); seg[id] = merge(seg[lid], seg[rid]); } void rem(int s, int ind, int l=0, int r=N, int id=1) { // if (id == 1) cout << "- " << arr[ind].F << " " << arr[ind].S << endl; if (l+1 == r) { seg[id].cnt--; seg[id].sigmaL -= arr[ind].F; seg[id].sigmaR -= arr[ind].S; return; } if (s < mid) rem(s, ind, l, mid, lid); else rem(s, ind, mid, r, rid); seg[id] = merge(seg[lid], seg[rid]); } D get(int s, int t, int l=0, int r=N, int id=1) { if (s >= t) return emp; if (s <= l && t >= r) return seg[id]; if (t <= mid) return get(s, t, l, mid, lid); if (s >= mid) return get(s, t, mid, r, rid); return merge(get(s, t, l, mid, lid), get(s, t, mid, r, rid)); } /* Segment Tree */ inline int cost(int x, int y) { int res = ps[0][x] + ps[1][y]; D cur; cur = get(0, id(cmp[x]+cmp[y])); res += cur.sigmaL - cmp[x]*cur.cnt; cur = get(id(cmp[x]+cmp[y]), N); res += cmp[y]*cur.cnt - cur.sigmaR; return res; } inline int delta(int x, int y) { int res = cost(x, y+1)-cost(x, y); res += cnt[1][y].size()-(upper_bound(all(cnt[1][y]), x)-cnt[1][y].begin()); return res; } int32_t main() { #ifdef LOCAL freopen("inp.in", "r", stdin); freopen("res.out", "w", stdout); #else ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #endif cin >> k >> n; N = 0; for (int i=1; i<=n; i++) { cin >> ch >> u >> ch2 >> v; if (ch == ch2) res += abs(u-v); else arr[++N] = {u, v}; } n = N; pre_ans = res; res += solve1(); if (k == 1) kill(res); for (int i=1; i<=n; i++) { u = arr[i].F; v = arr[i].S; if (u > v) swap(arr[i].F, arr[i].S); pre_ans += abs(arr[i].F-arr[i].S)+1; cmp.pb(u); cmp.pb(v); cmp.pb(u+v); } sort(all(cmp)); cmp.resize(unique(all(cmp))-cmp.begin()); N = cmp.size(); emp.sigmaL = emp.sigmaR = emp.cnt = 0; // cout << "@ " << endl; // for (int u:cmp) cout << u << " "; // cout << endl; for (int i=1; i<=n; i++) { u = di[i].F = id(arr[i].F); v = di[i].S = id(arr[i].S); // cnt[0][u]++; cnt[1][v]++; cnt[0][u].pb(v); cnt[1][v].pb(u); vec[0][u].pb(i); vec[1][v].pb(i); } for (int i=0; i<N; i++) { sort(all(cnt[0][i])); sort(all(cnt[1][i])); } tmp = tmp2 = 0; for (int i=0; i<N; i++) { ps[0][i] = cmp[i]*tmp2-tmp; for (int ind:vec[1][i]) { tmp2++; tmp += arr[ind].S; } } tmp = tmp2 = 0; for (int i=N-1; i>=0; i--) { ps[1][i] = tmp-cmp[i]*tmp2; for (int ind:vec[0][i]) { tmp2++; tmp += arr[ind].F; } } // for (int i=1; i<=n; i++) add(id(arr[i].F+arr[i].S), i); ans = INF; int j = 1; for (int i=0; i<N; i++) { for (auto ind:vec[0][i]) { if (di[ind].S >= j) continue; rem(id(arr[ind].F+arr[ind].S), ind); } while (j+1 < N && (j <= i || delta(i, j) < 0)) { for (auto ind:vec[1][j]) { if (di[ind].F <= i) continue; add(id(arr[ind].F+arr[ind].S), ind); } j++; } // cout << "! " << i << " " << j << " " << pre_ans+2*cost(i, j) << endl; ans = min(ans, pre_ans+2*cost(i, j)); } // cout << ans << " " << res << endl; cout << min(ans, res) << endl; 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...