結果
| 問題 |
No.2292 Interval Union Find
|
| コンテスト | |
| ユーザー |
rniya
|
| 提出日時 | 2023-05-05 22:07:24 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 200 ms / 5,000 ms |
| コード長 | 5,878 bytes |
| コンパイル時間 | 2,109 ms |
| コンパイル使用メモリ | 203,392 KB |
| 最終ジャッジ日時 | 2025-02-12 18:20:05 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 44 |
ソースコード
#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif
template <typename S, typename T> struct IntervalManager {
struct node {
T l, r;
S x;
node(T l, T r, S x) : l(l), r(r), x(x) {}
constexpr bool operator<(const node& rhs) const { return l != rhs.l ? l < rhs.l : r < rhs.r; }
};
const S id = S();
std::set<node> s;
IntervalManager() {}
IntervalManager(const std::vector<S>& v) {
std::vector<node> tmp;
for (size_t l = 0; l < v.size();) {
size_t r = l;
while (r < v.size() and v[l] == v[r]) r++;
tmp.emplace_back(l, r, v[l]);
l = r;
}
s = std::set<node>(tmp.begin(), tmp.end());
}
typename std::set<node>::iterator getItr(const T& x) const {
auto itr = s.upper_bound(node(x, std::numeric_limits<T>::max(), id));
if (itr == s.begin()) return s.end();
itr = prev(itr);
return itr->l <= x and x < itr->r ? itr : s.end();
}
node getSeg(const T& x) const {
auto itr = getItr(x);
return itr != s.end() ? *itr : node(x, x + 1, id);
}
S get(const T& x) const {
auto seg = getSeg(x);
return seg.x;
}
S operator[](const T& x) const { return get(x); }
template <typename ADD, typename DEL> void apply(T l, T r, const S& x, const ADD& add, const DEL& del) {
auto itr = s.lower_bound(node(l, std::numeric_limits<T>::min(), id));
while (itr != s.end() and itr->l <= r) {
if (itr->l == r) {
if (itr->x == x) {
del(itr->l, itr->r, itr->x);
r = itr->r;
itr = s.erase(itr);
}
break;
}
if (itr->r <= r) {
del(itr->l, itr->r, itr->x);
itr = s.erase(itr);
} else {
if (itr->x == x) {
r = itr->r;
del(itr->l, itr->r, itr->x);
itr = s.erase(itr);
} else {
del(itr->l, r, itr->x);
node tmp = *itr;
itr = s.erase(itr);
itr = s.emplace_hint(itr, r, tmp.r, tmp.x);
}
}
}
if (itr != s.begin()) {
itr = prev(itr);
if (itr->r == l) {
if (itr->x == x) {
del(itr->l, itr->r, itr->x);
l = itr->l;
itr = s.erase(itr);
}
} else if (l < itr->r) {
if (itr->x == x) {
del(itr->l, itr->r, itr->x);
l = std::min(l, itr->l);
r = std::max(r, itr->r);
itr = s.erase(itr);
} else {
if (r < itr->r) {
itr = s.emplace_hint(next(itr), r, itr->r, itr->x);
itr = prev(itr);
}
del(l, std::min(r, itr->r), itr->x);
node tmp = *itr;
itr = s.erase(itr);
itr = s.emplace_hint(itr, tmp.l, l, tmp.x);
}
}
}
add(l, r, x);
s.emplace(l, r, x);
}
void apply(T l, T r, const S& x) {
apply(
l, r, x, [](T, T, S) {}, [](T, T, S) {});
}
friend std::ostream& operator<<(std::ostream& os, const IntervalManager& im) {
for (const auto& e : im) os << "([" << e.l << ", " << e.r << "): " << e.x << ") ";
os << "\n";
return os;
}
};
using namespace std;
typedef long long ll;
#define all(x) begin(x), end(x)
constexpr int INF = (1 << 30) - 1;
constexpr long long IINF = (1LL << 60) - 1;
constexpr int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
template <class T> istream& operator>>(istream& is, vector<T>& v) {
for (auto& x : v) is >> x;
return is;
}
template <class T> ostream& operator<<(ostream& os, const vector<T>& v) {
auto sep = "";
for (const auto& x : v) os << exchange(sep, " ") << x;
return os;
}
template <class T, class U = T> bool chmin(T& x, U&& y) { return y < x and (x = forward<U>(y), true); }
template <class T, class U = T> bool chmax(T& x, U&& y) { return x < y and (x = forward<U>(y), true); }
template <class T> void mkuni(vector<T>& v) {
sort(begin(v), end(v));
v.erase(unique(begin(v), end(v)), end(v));
}
template <class T> int lwb(const vector<T>& v, const T& x) { return lower_bound(begin(v), end(v), x) - begin(v); }
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q;
cin >> N >> Q;
IntervalManager<int, int> IM;
auto add = [&](int l, int r, int x) {};
auto del = [&](int l, int r, int x) {};
for (; Q--;) {
int type;
cin >> type;
if (type == 1) {
int L, R;
cin >> L >> R;
IM.apply(L, R, 1, add, del);
} else if (type == 2) {
int L, R;
cin >> L >> R;
IM.apply(L, R, 0, add, del);
} else if (type == 3) {
int u, v;
cin >> u >> v;
if (u > v) swap(u, v);
if (u == v) {
cout << 1 << '\n';
continue;
}
auto seg = IM.getSeg(u);
cout << (seg.x == 1 and seg.r > v - 1) << '\n';
} else {
int v;
cin >> v;
auto seg = IM.getSeg(v);
debug(v, seg.l, seg.r);
int ans = (seg.x == 0 ? 1 : seg.r - seg.l + 1);
auto nseg = IM.getSeg(v - 1);
if (seg.l != nseg.l and seg.r != nseg.r and nseg.x == 1) ans += nseg.r - nseg.l;
cout << ans << '\n';
}
}
return 0;
}
rniya