제출 #197074

#제출 시각아이디문제언어결과실행 시간메모리
197074popovicirobert전선 연결 (IOI17_wiring)C++14
100 / 100
223 ms22764 KiB
#include "wiring.h" #include <bits/stdc++.h> #define ll long long using namespace std; static const ll INF = 1e18; struct Node { ll mn; Node(ll _mn = INF) : mn(_mn) { } }; class SegTree { public: vector <Node> aint; int n; inline void init(int _n) { n = _n; aint.resize(4 * n + 5); } inline void update(int l, int r, Node cur) { // l == r ??? update(1, 0, n, l, r, cur); } inline Node query(int l, int r) { return query(1, 0, n, l, r); } private: inline Node combine(Node a, Node b) { return Node(min(a.mn, b.mn)); } void update(int nod, int left, int right, int l, int r, Node cur) { if(l <= left && right <= r) { aint[nod] = combine(aint[nod], cur); return ; } int mid = (left + right) / 2; if(l <= mid) update(2 * nod, left, mid, l, r, cur); if(mid < r) update(2 * nod + 1, mid + 1, right, l, r, cur); aint[nod] = combine(aint[2 * nod], aint[2 * nod + 1]); } Node query(int nod, int left, int right, int l, int r) { if(l <= left && right <= r) { return aint[nod]; } int mid = (left + right) / 2; Node ans(INF); if(l <= mid) ans = combine(ans, query(2 * nod, left, mid, l, r)); if(mid < r) ans = combine(ans, query(2 * nod + 1, mid + 1, right, l, r)); return ans; } }; ll min_total_length(vector<int> r, vector<int> b) { vector < pair <int, int> > x(1); for(auto it : r) { x.push_back({it, 0}); } for(auto it : b) { x.push_back({it, 1}); } sort(x.begin(), x.end()); int i, n = r.size() + b.size(); vector <int> last(n + 1, 0), nxt(n + 2, n + 1); vector <ll> sp(n + 1); for(i = 1; i <= n; i++) { last[i] = ((x[i].second ^ x[i - 1].second) ? i - 1 : last[i - 1]); sp[i] = sp[i - 1] + x[i].first; //cerr << x[i].first << " "; } for(i = n; i >= 1; i--) { nxt[i] = ((x[i].second ^ x[i + 1].second) ? i + 1 : nxt[i + 1]); } SegTree st1, st2; st1.init(n), st2.init(n); vector <ll> dp(n + 1); for(i = 1; i <= n; i++) { st1.update(i - 1, i - 1, Node(dp[i - 1] - 1LL * (i - 1) * x[nxt[i] - 1].first + sp[i - 1])); st2.update(i - 1, i - 1, Node(dp[i - 1] - 1LL * (i - 1) * x[nxt[i] - 1].first + sp[i - 1] + 1LL * (nxt[i] - i) * (x[nxt[i]].first - x[nxt[i] - 1].first))); if(last[i] == 0) { dp[i] = INF; continue; } int a = last[i] - last[last[i]], b = i - last[i]; ll cur = sp[i] - sp[last[i]] - 1LL * (i - last[i]) * x[last[i] + 1].first - sp[last[i]] + 1LL * x[last[i]].first * last[i]; dp[i] = cur + 1LL * (i - last[i]) * (x[last[i] + 1].first - x[last[i]].first) + st1.query(max(0, last[i] - b), last[i] - 1).mn; if(a > b) { dp[i] = min(dp[i], cur + st2.query(last[last[i]], last[i] - b).mn); } if(a == 1) { dp[i] = min(dp[last[i]] + sp[i] - sp[last[i]] - 1LL * x[last[i]].first * b, dp[i]); } } return dp[n]; }
#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...