제출 #1039867

#제출 시각아이디문제언어결과실행 시간메모리
1039867RecursiveCo봉쇄 시간 (IOI23_closing)C++17
8 / 100
82 ms32092 KiB
// CF template, version 3.0 #include <bits/stdc++.h> using namespace std; #define improvePerformance ios_base::sync_with_stdio(false); cin.tie(0) #define getTest int t; cin >> t #define eachTest for (int _var=0;_var<t;_var++) #define get(name) int (name); cin >> (name) #define out(o) cout << (o) #define getList(cnt, name) vector<int> (name); for (int _=0;_<(cnt);_++) { get(a); (name).push_back(a); } #define sortl(name) sort((name).begin(), (name).end()) #define rev(name) reverse((name).begin(), (name).end()) #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++) #define decision(b) if (b){out("YES");}else{out("NO");} //#define int long long int template <typename T, typename I> struct segtree { int n; vector<T> tree; vector<I> initial; T id; segtree(int i_n, vector<I> i_initial, T i_id): n(i_n), initial(i_initial), id(i_id) { tree.resize(4 * n); } T conquer(T left, T right) { // write your conquer function } T value(I inp) { // write your value function } void build(int v, int l, int r) { if (l == r) tree[v] = value(initial[l]); else { int middle = (l + r) / 2; build(2 * v, l, middle); build(2 * v + 1, middle + 1, r); tree[v] = conquer(tree[2 * v], tree[2 * v + 1]); } } void upd(int v, int l, int r, int i, I x) { if (l == r) tree[v] = value(x); else { int middle = (l + r) / 2; if (middle >= i) upd(2 * v, l, middle, i, x); else upd(2 * v + 1, middle + 1, r, i, x); tree[v] = conquer(tree[2 * v], tree[2 * v + 1]); } } T query(int v, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return tree[v]; else if (r < ql || qr < l) return id; int middle = (l + r) / 2; T left = query(2 * v, l, middle, ql, qr); T right = query(2 * v + 1, middle + 1, r, ql, qr); return conquer(left, right); } }; // vector<int> vector<vector<pair<int, int>>> adjList; vector<long long> fromX; vector<long long> fromY; void dfs(int v, int p, long long d, int which) { if (which) fromY[v] = d; else fromX[v] = d; for (auto pa: adjList[v]) { int con = pa.first; long long w = pa.second; if (con == p) continue; dfs(con, v, d + w, which); } } int max_score(int N, int X, int Y, long long K, vector<int> U, vector<int> V, vector<int> W) { adjList.clear(); adjList.resize(N); fromX.clear(); fromX.resize(N); fromY.clear(); fromY.resize(N); forto(N - 1, i) { int a = U[i]; int b = V[i]; int w = W[i]; adjList[a].push_back({b, w}); adjList[b].push_back({a, w}); } dfs(X, -1, 0ll, 0); dfs(Y, -1, 0ll, 1); int ans = 0; if (fromY[X] > 2 * K) { vector<long long> paths; forto(N, i) { paths.push_back(min(fromX[i], fromY[i])); } sortl(paths); long long sum = 0; forto(N, i) { if (sum + paths[i] > K) break; sum += paths[i]; ans++; } } else { long long C = fromX[Y]; // = fromY[X] // CASE 1: Stuff gets taken twice on both sides. // Everything in the middle gets taken twice. // Greedy/bruteforce on the sides. int ans1 = 0; long long sum1 = 0; int middle1 = 0; vector<long long> sides1; forto(N, i) { long long val = max(fromX[i], fromY[i]); if (val < C) sum1 += val, middle1++; else sides1.push_back(min(fromX[i], fromY[i])); } sortl(sides1); int s1 = sides1.size(); if (sum1 <= K) ans1 = max(ans1, 2 * middle1); forto(s1, i) { if (sum1 + sides1[i] > K) break; sum1 += sides1[i]; long long extral = (K - sum1) / C; int extra; if (extral > (long long) i + 1) extra = i + 1; else extra = (int) extral; ans1 = max(ans1, 2 * middle1 + (i + 1) + extra); } // CASE 2: Stuff gets taken twice on one of the two sides. // Everything in the middle gets taken once. // Suppose wlog the twice-taken stuff occurs on Y's side, then some suffix spanning to at least the halfway point of the middle must get taken twice. // CASE 2.1: On Y's side. int ans21 = 0; long long sum21 = 0; int middle21 = 0; vector<long long> delta21; vector<long long> side21; forto(N, i) { long long val = min(fromX[i], fromY[i]); if (max(fromX[i], fromY[i]) < C) sum21 += val, middle21++; if (max(fromX[i], fromY[i]) < C) { if (2 * fromY[i] <= C) sum21 += max(fromX[i], fromY[i]) - val, middle21++; else delta21.push_back(fromY[i] - fromX[i]); } else if (fromX[i] <= fromY[i]) { delta21.push_back(fromX[i]); } else { side21.push_back(fromY[i]); } } sortl(delta21); sortl(side21); if (sum21 <= K) ans21 = max(ans21, middle21); int ds21 = delta21.size(); int s21 = side21.size(); forto(ds21, i) { if (sum21 + delta21[i] > K) break; sum21 += delta21[i]; long long here = sum21; forto(s21, j) { if (here + side21[i] > K) break; here += side21[i]; long long extral = (K - here) / C; int extra; if (extral > (long long) j + 1) extra = j + 1; else extra = (int) extral; ans21 = max(ans21, middle21 + (i + 1) + (j + 1) + extra); } } // CASE 2.2: On X's side. int ans22 = 0; long long sum22 = 0; int middle22 = 0; vector<long long> delta22; vector<long long> side22; forto(N, i) { long long val = min(fromX[i], fromY[i]); if (max(fromX[i], fromY[i]) < C) sum22 += val, middle22++; if (max(fromX[i], fromY[i]) < C) { if (2 * fromX[i] <= C) sum22 += max(fromX[i], fromY[i]) - val, middle22++; else delta22.push_back(fromX[i] - fromY[i]); } else if (fromY[i] <= fromX[i]) { delta22.push_back(fromY[i]); } else { side22.push_back(fromX[i]); } } sortl(delta22); sortl(side22); if (sum22 <= K) ans22 = max(ans22, middle22); int ds22 = delta22.size(); int s22 = side22.size(); forto(ds22, i) { if (sum22 + delta22[i] > K) break; sum22 += delta22[i]; long long here = sum22; forto(s22, j) { if (here + side22[i] > K) break; here += side22[i]; long long extral = (K - here) / C; int extra; if (extral > (long long) j + 1) extra = j + 1; else extra = (int) extral; ans22 = max(ans22, middle22 + (i + 1) + (j + 1) + extra); } } // CASE 3: Nothing on the sides gets taken twice. // Then we greedy on the sides while solving the problem in the middle. // Yeah O(n^2log(n)) passes. Pretty sure. int ans3 = 0; vector<long long> sides3; vector<long long> midsmall3; vector<long long> middelta3; long long midsum3 = 0; forto(N, i) { long long val = max(fromX[i], fromY[i]); if (val < C) { midsmall3.push_back(min(fromX[i], fromY[i])); middelta3.push_back(val - min(fromX[i], fromY[i])); midsum3 += min(fromX[i], fromY[i]); } else { sides3.push_back(min(fromX[i], fromY[i])); } } sortl(sides3); sortl(midsmall3); sortl(middelta3); int s3 = sides3.size(); int ms3 = midsmall3.size(); int md3 = middelta3.size(); long long sum3 = 0; forto(s3, i) { if (sum3 + sides3[i] > K) break; sum3 += sides3[i]; long long tot = sum3; forto(ms3, j) { if (tot + midsmall3[j] > K) break; tot += midsmall3[j]; ans3 = max(ans3, (i + 1) + (j + 1)); } if (sum3 + midsum3 <= K) { long long higher = sum3 + midsum3; forto(md3, j) { if (higher + middelta3[j] > K) break; higher += middelta3[j]; ans3 = max(ans3, (i + 1) + ms3 + (j + 1)); } } } ans = max({ans1, ans21, ans22, ans3}); } return ans; }

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

closing.cpp: In function 'int max_score(int, int, int, long long int, std::vector<int>, std::vector<int>, std::vector<int>)':
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:93:5: note: in expansion of macro 'forto'
   93 |     forto(N - 1, i) {
      |     ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:105:9: note: in expansion of macro 'forto'
  105 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:110:9: note: in expansion of macro 'forto'
  110 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:124:9: note: in expansion of macro 'forto'
  124 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:132:9: note: in expansion of macro 'forto'
  132 |         forto(s1, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:151:9: note: in expansion of macro 'forto'
  151 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:168:9: note: in expansion of macro 'forto'
  168 |         forto(ds21, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:172:13: note: in expansion of macro 'forto'
  172 |             forto(s21, j) {
      |             ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:189:9: note: in expansion of macro 'forto'
  189 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:206:9: note: in expansion of macro 'forto'
  206 |         forto(ds22, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:210:13: note: in expansion of macro 'forto'
  210 |             forto(s22, j) {
      |             ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:229:9: note: in expansion of macro 'forto'
  229 |         forto(N, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:246:9: note: in expansion of macro 'forto'
  246 |         forto(s3, i) {
      |         ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:250:13: note: in expansion of macro 'forto'
  250 |             forto(ms3, j) {
      |             ^~~~~
closing.cpp:15:35: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   15 | #define forto(name, var) for (int (var) = 0; (var) < (name); (var)++)
      |                                   ^
closing.cpp:257:17: note: in expansion of macro 'forto'
  257 |                 forto(md3, j) {
      |                 ^~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...