This documentation is automatically generated by online-judge-tools/verification-helper
#include "Library/DataStructure/RollbackUnionFind.hpp"通常の Union-Find に加え、次の操作を可能としたデータ構造。
Unite 操作の取り消しRollbackUnionFind(size_t n)
制約
計算量
int Find(const int k)
制約
計算量
bool Same(const int x, const int y)
true を返します。制約
計算量
bool Unite(int x, int y)
true を返します。制約
計算量
size_t Size(int k)
制約
計算量
vector<vector<int>> Group()
計算量
void Record()
計算量
void Undo()
Unite 操作を取り消します。計算量
void Rollback()
Record で記録した状態まで Unite 操作を取り消します。Record を $1$ 度も呼び出していない場合はすべての操作を取り消します。計算量
Unite 操作の回数を $k$ として、$\textrm{O}(k)$#include "../Common.hpp"
class RollbackUnionFind{
public:
RollbackUnionFind(size_t n) : data_(n, -1), record_(0){}
int Find(const int k) const {
if(data_[k] < 0) return k;
return Find(data_[k]);
}
bool Same(const int x, const int y) const {
return Find(x) == Find(y);
}
bool Unite(int x, int y){
x = Find(x), y = Find(y);
history_.push({x, data_[x]});
history_.push({y, data_[y]});
if(x == y) return false;
if(data_[x] > data_[y]) swap(x, y);
data_[x] += data_[y];
data_[y] = x;
return true;
}
int Size(const int k) const {
return -data_[Find(k)];
}
vector<vector<int>> Group() const {
vector<vector<int>> ret(data_.size());
for(int i = 0; i < data_.size(); ++i){
ret[Find(i)].emplace_back(i);
}
ret.erase(remove_if(begin(ret), end(ret), [&](vector<int> &v){
return v.empty();
}), end(ret));
return ret;
}
void Record(){
record_ = history_.size();
}
void Undo(){
auto [y, dy] = history_.top();
history_.pop();
data_[y] = dy;
auto [x, dx] = history_.top();
history_.pop();
data_[x] = dx;
}
void Rollback(){
int state = record_;
while(state < (int)history_.size()) Undo();
}
private:
vector<int> data_;
stack<pair<int, int>> history_;
int record_;
};#line 2 "Library/Common.hpp"
/**
* @file Common.hpp
*/
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
constexpr const ll INF = (1LL << 62) - (3LL << 30) - 1;
#line 2 "Library/DataStructure/RollbackUnionFind.hpp"
class RollbackUnionFind{
public:
RollbackUnionFind(size_t n) : data_(n, -1), record_(0){}
int Find(const int k) const {
if(data_[k] < 0) return k;
return Find(data_[k]);
}
bool Same(const int x, const int y) const {
return Find(x) == Find(y);
}
bool Unite(int x, int y){
x = Find(x), y = Find(y);
history_.push({x, data_[x]});
history_.push({y, data_[y]});
if(x == y) return false;
if(data_[x] > data_[y]) swap(x, y);
data_[x] += data_[y];
data_[y] = x;
return true;
}
int Size(const int k) const {
return -data_[Find(k)];
}
vector<vector<int>> Group() const {
vector<vector<int>> ret(data_.size());
for(int i = 0; i < data_.size(); ++i){
ret[Find(i)].emplace_back(i);
}
ret.erase(remove_if(begin(ret), end(ret), [&](vector<int> &v){
return v.empty();
}), end(ret));
return ret;
}
void Record(){
record_ = history_.size();
}
void Undo(){
auto [y, dy] = history_.top();
history_.pop();
data_[y] = dy;
auto [x, dx] = history_.top();
history_.pop();
data_[x] = dx;
}
void Rollback(){
int state = record_;
while(state < (int)history_.size()) Undo();
}
private:
vector<int> data_;
stack<pair<int, int>> history_;
int record_;
};