제출 #500396

#제출 시각아이디문제언어결과실행 시간메모리
500396600MihneaCollapse (JOI18_collapse)C++17
100 / 100
2932 ms20384 KiB
#include "collapse.h" #include <bits/stdc++.h> using namespace std; const int NN = 100000 + 7; int dsu[2][NN], un[2], lt[2][NN], tt[2]; void initial(int id) { assert(0 <= id && id < 2); un[id] = 0; for (int i = 0; i < NN; i++) { dsu[id][i] = i; } } int root(int id, int a) { if (lt[id][a] != tt[id]) { dsu[id][a] = a; lt[id][a] = tt[id]; } if (a == dsu[id][a]) { return a; } else { return dsu[id][a] = root(id, dsu[id][a]); } } void unite(int id, int a, int b) { // if (id == 1) { // } a = root(id, a); b = root(id, b); if (id) { lt[id][a] = tt[id]; lt[id][b] = tt[id]; } if (a != b) { un[id]++; dsu[id][a] = b; } } const int edgeM = 333; vector<int> smart(int n, vector<int> T, vector<int> X, vector<int> Y, vector<int> w, vector<int> p) { initial(0); initial(1); struct Edge { int type; int x; int y; int id; }; vector<Edge> edges; int m = (int)T.size(); int q = (int)w.size(); bool ok = (n <= 5000 && q <= 5000 && m <= 5000); vector<pair<int, int>> theEdge; vector<int> active; { map<pair<int, int>, int> inds; int kek = 0; for (int i = 0; i < m; i++) { if (X[i] > Y[i]) { swap(X[i], Y[i]); } if (!inds.count({X[i], Y[i]})) { inds[{X[i], Y[i]}] = kek++; theEdge.push_back({X[i], Y[i]}); active.push_back(0); } edges.push_back({T[i], X[i], Y[i], inds[{X[i], Y[i]}]}); } } function<bool(int, int)> cmp = [&] (int i, int j) { return p[i] < p[j]; }; function<bool(int, int)> cmpE = [&] (int i, int j) { return theEdge[i].second < theEdge[j].second; }; assert((int) T.size() == m); assert((int) X.size() == m); assert((int) Y.size() == m); assert((int) w.size() == q); assert((int) p.size() == q); vector<int> sol((int) w.size()); for (int ISTEP = 1; ISTEP <= 2; ISTEP++) { for (auto &x : active) { x = 0; } vector<int> edgeBucket(m), edgeFirst(m), edgeLast(m); vector<int> O; for (int i = 0; i < m; i++) { edgeBucket[i] = i / edgeM; edgeLast[edgeBucket[i]] = i; } for (int i = m - 1; i >= 0; i--) { edgeFirst[edgeBucket[i]] = i; } vector<vector<int>> inds(m); for (int i = 0; i < q; i++) { inds[w[i]].push_back(i); } vector<int> order((int) active.size()); iota(order.begin(), order.end(), 0); sort(order.begin(), order.end(), cmpE); for (int edgeBucketId = edgeBucket[0]; edgeBucketId <= edgeBucket[m - 1]; edgeBucketId++) { // cout << ISTEP << ", " << edgeBucketId << " out of " << edgeBucket[m - 1] << "\n"; tt[0]++; tt[1]++; un[0] = un[1] = 0; vector<bool> use_now((int) active.size(), 0); vector<int> current = active; vector<int> guys; for (int step = edgeFirst[edgeBucketId]; step <= edgeLast[edgeBucketId]; step++) { use_now[edges[step].id] = 1; for (auto &iq : inds[step]) { guys.push_back(iq); } } vector<pair<int, int>> additional; vector<int> here; for (auto &i : order) { if (use_now[i]) { here.push_back(i); } if (active[i] && !use_now[i]) { additional.push_back(theEdge[i]); } } int ptr = 0; sort(guys.begin(), guys.end(), cmp); for (auto &iq : guys) { tt[1]++; un[1] = 0; for (int step = edgeFirst[edgeBucketId]; step <= w[iq]; step++) { current[edges[step].id] ^= 1; } vector<pair<int, int>> specific; for (auto &i : here) { if (current[i]) { specific.push_back(theEdge[i]); } } for (int step = edgeFirst[edgeBucketId]; step <= w[iq]; step++) { current[edges[step].id] = active[edges[step].id]; } while (ptr < (int) additional.size() && additional[ptr].second <= p[iq]) { unite(0, additional[ptr].first, additional[ptr].second); ptr++; } // assert((int) specific.size() <= edgeM); //if (!ok) continue; for (auto &it : specific) { if (it.second <= p[iq]) { unite(1, root(0, it.first), root(0, it.second)); } } sol[iq] += p[iq] + 1 - (un[0] + un[1]); } for (int step = edgeFirst[edgeBucketId]; step <= edgeLast[edgeBucketId]; step++) { active[edges[step].id] ^= 1; } } for (int i = 0; i < m; i++) { swap(edges[i].x, edges[i].y); edges[i].x = n - 1 - edges[i].x; edges[i].y = n - 1 - edges[i].y; } for (int i = 0; i < q; i++) { p[i] = n - 2 - p[i]; } for (auto &it : theEdge) { swap(it.first, it.second); it.first = n - 1 - it.first; it.second = n - 1 - it.second; } } return sol; } vector<int> simulateCollapse(int N, vector<int> T, vector<int> X, vector<int> Y, vector<int> W, vector<int> P) { return smart(N,T,X,Y,W,P); }

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

collapse.cpp: In function 'std::vector<int> smart(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
collapse.cpp:63:8: warning: unused variable 'ok' [-Wunused-variable]
   63 |   bool ok = (n <= 5000 && q <= 5000 && m <= 5000);
      |        ^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...