Submission #92334

#TimeUsernameProblemLanguageResultExecution timeMemory
92334Alexa2001Collapse (JOI18_collapse)C++17
100 / 100
4046 ms30684 KiB
#include <bits/stdc++.h> #include "collapse.h" using namespace std; const int Bsize = 323, Nmax = 1e5 + 5; struct Edge { int x, y, t1, t2; bool operator < (const Edge &other) const { return y < other.y; } }; struct Query { int pos, t, id; bool operator < (const Query &other) const { return pos < other.pos; } }; vector<int> answer; vector<Query> queries; vector<Edge> edges; map< pair<int,int> , int > mp; int N, Q, M; namespace forest { static int moves; static int t[Nmax], rang[Nmax]; static vector<int> S, T; void init() { moves = 0; S.clear(); T.clear(); int i; for(i=0; i<N; ++i) t[i] = i; } int boss(int node) { while(t[node] != node) node = t[node]; return node; } bool unite(int x, int y) { x = boss(x); y = boss(y); if(x == y) return 0; ++moves; if(rang[x] == rang[y]) { ++rang[y]; S.push_back(y); } else { S.push_back(0); if(rang[x] > rang[y]) swap(x, y); } t[x] = y; T.push_back(x); return 1; } void undo(int nr) { moves -= nr; while(nr--) { assert(S.size()); assert(T.size()); int x, y; x = T.back(), y = S.back(); S.pop_back(); T.pop_back(); t[x] = x; if(y) rang[y] --; } } } void solve(vector<Edge> E, vector<Query> Q) { int i; vector<Query> v[Nmax]; vector<Edge> all, possible; for(auto it : Q) v[it.t / Bsize * Bsize].push_back(it); for(i=0; i<=M; i += Bsize) if(!v[i].empty()) { forest::init(); all.clear(); possible.clear(); for(auto it : E) if(it.t1 <= i && it.t2 >= i + Bsize - 1) all.push_back(it); else if(it.t2 >= i && it.t1 <= i + Bsize - 1) possible.push_back(it); sort(all.begin(), all.end()); sort(v[i].begin(), v[i].end()); int cursor = 0; for(auto q : v[i]) { while(cursor < all.size() && all[cursor].y <= q.pos) forest::unite(all[cursor].x, all[cursor].y), ++cursor; int undo = 0; for(auto it : possible) if(it.t1 <= q.t && q.t <= it.t2 && it.y <= q.pos) if(forest::unite(it.x, it.y)) ++undo; answer[q.id] -= forest::moves; forest::undo(undo); } } } vector<int> simulateCollapse (int _N, vector<int> T, vector<int> X, vector<int> Y, vector<int> W, vector<int> P) { N = _N, M = T.size(), Q = W.size(); int i; answer.resize(Q); for(i=0; i<Q; ++i) answer[i] = N; for(i=0; i<M; ++i) { if(X[i] > Y[i]) swap(X[i], Y[i]); if(T[i] == 0) mp[{X[i], Y[i]}] = i; else { edges.push_back({X[i], Y[i], mp[{X[i], Y[i]}], i - 1}); mp[{X[i], Y[i]}] = -1; } } for(auto it : mp) if(it.second != -1) edges.push_back({it.first.first, it.first.second, it.second, M-1}); for(i=0; i<Q; ++i) queries.push_back({P[i], W[i], i}); solve(edges, queries); for(auto &it : edges) { it.x = N - it.x - 1, it.y = N - it.y - 1; swap(it.x, it.y); } for(auto &it : queries) it.pos = N - it.pos - 2; solve(edges, queries); return answer; }

Compilation message (stderr)

collapse.cpp: In function 'void solve(std::vector<Edge>, std::vector<Query>)':
collapse.cpp:114:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while(cursor < all.size() && all[cursor].y <= q.pos)
                   ~~~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...