제출 #425205

#제출 시각아이디문제언어결과실행 시간메모리
425205two_sides고대 책들 (IOI17_books)C++17
0 / 100
2108 ms825580 KiB
#include "books.h" #include <bits/stdc++.h> using namespace std; namespace { #define fi first #define se second using ll = long long; struct segment_tree { #define il i * 2 #define ir i * 2 + 1 vector <int> val; int n, x, y, res; void build(int i, int l, int r, const vector <int> &idx) { if (l == r) val[i] = idx[l]; else { int m = (l + r) / 2; build(il, l, m, idx); build(ir, m + 1, r, idx); val[i] = max(val[il], val[ir]); } } void init(const vector <int> &idx) { n = idx.size(); val.resize(n * 4); build(1, 0, n - 1, idx); } void init(int n) { this->n = n; val.assign(n * 4, -1e9); } void rep(int i, int l, int r, int v) { if (l == r) val[i] = v; else { int m = (l + r) / 2; if (m >= x) rep(il, l, m, v); else rep(ir, m + 1, r, v); val[i] = max(val[il], val[ir]); } } void get(int i, int l, int r) { if (l >= x && r <= y) { res = max(res, val[i]); return; } int m = (l + r) / 2; if (m >= x) get(il, l, m); if (m < y) get(ir, m + 1, r); } void rep(int p, int v) { x = p; rep(1, 0, n - 1, v); } int get(int l, int r) { x = l; y = r; res = -1e9; get(1, 0, n - 1); return res; } }; vector <int> lef, rig, scc; vector <vector <int>> own, cmp; segment_tree seg1, seg2; int timer = 0; stack <int> stk; vector <int> num, low; void tarjan(int u) { low[u] = num[u] = ++timer; for (int i : own[u]) { seg1.rep(i, -1); seg2.rep(i, -low[u]); } stk.push(u); int v = seg1.get(lef[u], rig[u]); while (~v) { tarjan(v); low[u] = min(low[u], low[v]); } low[u] = min(low[u], -seg2.get(lef[u], rig[u])); if (num[u] == low[u]) { cmp.emplace_back(); do { v = stk.top(); stk.pop(); cmp.back().push_back(v); scc[v] = cmp.size() - 1; num[v] = low[v] = 1e9; scc[v] = timer; } while (v != u); } } } ll minimum_walk(vector<int> p, int s) { int cnt = 0, n = p.size(); vector <int> idx(n, -1); for (int i = 0; i < n; i++) { if (~idx[i]) continue; int u = i; lef.push_back(i); rig.push_back(i); own.emplace_back(); while (idx[u] < 0) { own[cnt].push_back(u); lef[cnt] = min(lef[cnt], u); rig[cnt] = max(rig[cnt], u); idx[u] = cnt; u = p[u]; } cnt++; } scc.resize(cnt); num.resize(cnt); low.resize(cnt); seg1.init(idx); seg2.init(n); for (int i = 0; i < cnt; i++) if (!num[i]) tarjan(i); reverse(cmp.begin(), cmp.end()); num.assign(cmp.size(), 0); vector <pair <int, int>> tmp; int mi = s, ma = s; seg1.init(idx); seg2.init(n); for (int i = 0; i < cmp.size(); i++) { if (!num[i]) { int l = -1, r = n; for (int j : cmp[i]) for (int k : own[j]) { if (k < s) l = max(l, k); if (k > s) r = min(r, k); seg1.rep(k, -1); } if (l >= 0 && r < n) { tmp.emplace_back(l, r); seg2.rep(r, r); } else if (l >= 0) mi = min(mi, l); else if (r < n) ma = max(ma, r); } // for (int j : cmp[i]) // for (int k : own[j]) // seg1.rep(k, -1); // for (int j : cmp[i]) { // int k = seg1.get(lef[j], rig[j]); // while (k >= 0) { // num[scc[k]] = true; // for (int l : own[k]) // seg1.rep(l, -1); // k = seg1.get(lef[j], rig[j]); // } // } } sort(tmp.rbegin(), tmp.rend()); long long res = 2ll * (max(ma, seg2.val[1]) - mi); for (auto &p : tmp) { seg2.rep(p.se, -1); res = min(res, 2ll * (max(ma, seg2.val[1]) - min(mi, p.fi))); } for (int i = 0; i < n; i++) res += abs(i - p[i]); return res; return 0; }

컴파일 시 표준 에러 (stderr) 메시지

books.cpp: In function '{anonymous}::ll minimum_walk(std::vector<int>, int)':
books.cpp:131:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  131 |     for (int i = 0; i < cmp.size(); i++) {
      |                     ~~^~~~~~~~~~~~
#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...