QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#636338 | #21403. 文艺平衡树 | maspy | AC ✓ | 182ms | 8356kb | C++20 | 24.5kb | 2024-10-12 23:26:17 | 2024-10-12 23:26:18 |
Judging History
answer
#line 1 "/home/maspy/compro/library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない?
// #pragma GCC target("avx2,popcnt")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;
template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;
using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)
#define FOR_subset(t, s) for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define stoi stoll
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
template <typename T>
T floor(T a, T b) {
return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
T q = floor(x, y);
return {q, x - q * y};
}
template <typename T, typename U>
T SUM(const vector<U> &A) {
T sm = 0;
for (auto &&a: A) sm += a;
return sm;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()
template <typename T>
T POP(deque<T> &que) {
T a = que.front();
que.pop_front();
return a;
}
template <typename T>
T POP(pq<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(pqg<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(vc<T> &que) {
T a = que.back();
que.pop_back();
return a;
}
template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
if (check_ok) assert(check(ok));
while (abs(ok - ng) > 1) {
auto x = (ng + ok) / 2;
(check(x) ? ok : ng) = x;
}
return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
FOR(iter) {
double x = (ok + ng) / 2;
(check(x) ? ok : ng) = x;
}
return (ok + ng) / 2;
}
template <class T, class S>
inline bool chmax(T &a, const S &b) {
return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
return (a > b ? a = b, 1 : 0);
}
// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
vc<int> A(S.size());
FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
return A;
}
template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
int N = A.size();
vector<T> B(N + 1);
FOR(i, N) { B[i + 1] = B[i] + A[i]; }
if (off == 0) B.erase(B.begin());
return B;
}
// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
vector<int> ids(len(A));
iota(all(ids), 0);
sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
return ids;
}
// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
vc<T> B(len(I));
FOR(i, len(I)) B[i] = A[I[i]];
return B;
}
template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &... others) {
vc<T> &res = first;
(res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
#line 1 "/home/maspy/compro/library/other/io.hpp"
#define FASTIO
#include <unistd.h>
// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;
struct Pre {
char num[10000][4];
constexpr Pre() : num() {
for (int i = 0; i < 10000; i++) {
int n = i;
for (int j = 3; j >= 0; j--) {
num[i][j] = n % 10 | '0';
n /= 10;
}
}
}
} constexpr pre;
inline void load() {
memcpy(ibuf, ibuf + pil, pir - pil);
pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
pil = 0;
if (pir < SZ) ibuf[pir++] = '\n';
}
inline void flush() {
fwrite(obuf, 1, por, stdout);
por = 0;
}
void rd(char &c) {
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
}
void rd(string &x) {
x.clear();
char c;
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
do {
x += c;
if (pil == pir) load();
c = ibuf[pil++];
} while (!isspace(c));
}
template <typename T>
void rd_real(T &x) {
string s;
rd(s);
x = stod(s);
}
template <typename T>
void rd_integer(T &x) {
if (pil + 100 > pir) load();
char c;
do
c = ibuf[pil++];
while (c < '-');
bool minus = 0;
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (c == '-') { minus = 1, c = ibuf[pil++]; }
}
x = 0;
while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (minus) x = -x;
}
}
void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }
template <class T, class U>
void rd(pair<T, U> &p) {
return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
if constexpr (N < std::tuple_size<T>::value) {
auto &x = std::get<N>(t);
rd(x);
rd_tuple<N + 1>(t);
}
}
template <class... T>
void rd(tuple<T...> &tpl) {
rd_tuple(tpl);
}
template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
for (auto &d: x) rd(d);
}
void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
rd(h), read(t...);
}
void wt(const char c) {
if (por == SZ) flush();
obuf[por++] = c;
}
void wt(const string s) {
for (char c: s) wt(c);
}
void wt(const char *s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) wt(s[i]);
}
template <typename T>
void wt_integer(T x) {
if (por > SZ - 100) flush();
if (x < 0) { obuf[por++] = '-', x = -x; }
int outi;
for (outi = 96; x >= 10000; outi -= 4) {
memcpy(out + outi, pre.num[x % 10000], 4);
x /= 10000;
}
if (x >= 1000) {
memcpy(obuf + por, pre.num[x], 4);
por += 4;
} else if (x >= 100) {
memcpy(obuf + por, pre.num[x] + 1, 3);
por += 3;
} else if (x >= 10) {
int q = (x * 103) >> 10;
obuf[por] = q | '0';
obuf[por + 1] = (x - q * 10) | '0';
por += 2;
} else
obuf[por++] = x | '0';
memcpy(obuf + por, out + outi + 4, 96 - outi);
por += 96 - outi;
}
template <typename T>
void wt_real(T x) {
ostringstream oss;
oss << fixed << setprecision(15) << double(x);
string s = oss.str();
wt(s);
}
void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }
template <class T, class U>
void wt(const pair<T, U> val) {
wt(val.first);
wt(' ');
wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
if constexpr (N < std::tuple_size<T>::value) {
if constexpr (N > 0) { wt(' '); }
const auto x = std::get<N>(t);
wt(x);
wt_tuple<N + 1>(t);
}
}
template <class... T>
void wt(tuple<T...> tpl) {
wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
template <class T>
void wt(const vector<T> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
wt(head);
if (sizeof...(Tail)) wt(' ');
print(forward<Tail>(tail)...);
}
// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;
#if defined(LOCAL)
#define SHOW(...) SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) print(#x, "=", (x)), flush()
#define SHOW2(x, y) print(#x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) print(#x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v)), flush()
#define SHOW6(x, y, z, w, v, u) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v), #u, "=", (u)), flush()
#else
#define SHOW(...)
#endif
#define INT(...) \
int __VA_ARGS__; \
read(__VA_ARGS__)
#define LL(...) \
ll __VA_ARGS__; \
read(__VA_ARGS__)
#define U32(...) \
u32 __VA_ARGS__; \
read(__VA_ARGS__)
#define U64(...) \
u64 __VA_ARGS__; \
read(__VA_ARGS__)
#define STR(...) \
string __VA_ARGS__; \
read(__VA_ARGS__)
#define CHAR(...) \
char __VA_ARGS__; \
read(__VA_ARGS__)
#define DBL(...) \
double __VA_ARGS__; \
read(__VA_ARGS__)
#define VEC(type, name, size) \
vector<type> name(size); \
read(name)
#define VV(type, name, h, w) \
vector<vector<type>> name(h, vector<type>(w)); \
read(name)
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"
#line 2 "/home/maspy/compro/library/ds/splaytree/splaytree.hpp"
// Node 型を別に定義して使う
template <typename Node>
struct SplayTree {
Node *pool;
const int NODES;
int pid;
using np = Node *;
using X = typename Node::value_type;
using A = typename Node::operator_type;
vc<np> FREE;
SplayTree(int NODES) : NODES(NODES), pid(0) { pool = new Node[NODES]; }
~SplayTree() { delete[] pool; }
void free_subtree(np c) {
auto dfs = [&](auto &dfs, np c) -> void {
if (c->l) dfs(dfs, c->l);
if (c->r) dfs(dfs, c->r);
FREE.eb(c);
};
dfs(dfs, c);
}
void reset() {
pid = 0;
FREE.clear();
}
np new_root() { return nullptr; }
np new_node(const X &x) {
assert(!FREE.empty() || pid < NODES);
np n = (FREE.empty() ? &(pool[pid++]) : POP(FREE));
Node::new_node(n, x);
return n;
}
np new_node(const vc<X> &dat) {
auto dfs = [&](auto &dfs, int l, int r) -> np {
if (l == r) return nullptr;
if (r == l + 1) return new_node(dat[l]);
int m = (l + r) / 2;
np l_root = dfs(dfs, l, m);
np r_root = dfs(dfs, m + 1, r);
np root = new_node(dat[m]);
root->l = l_root, root->r = r_root;
if (l_root) l_root->p = root;
if (r_root) r_root->p = root;
root->update();
return root;
};
return dfs(dfs, 0, len(dat));
}
u32 get_size(np root) { return (root ? root->size : 0); }
np merge(np l_root, np r_root) {
if (!l_root) return r_root;
if (!r_root) return l_root;
assert((!l_root->p) && (!r_root->p));
splay_kth(r_root, 0); // splay したので prop 済
r_root->l = l_root;
l_root->p = r_root;
r_root->update();
return r_root;
}
np merge3(np a, np b, np c) { return merge(merge(a, b), c); }
np merge4(np a, np b, np c, np d) { return merge(merge(merge(a, b), c), d); }
pair<np, np> split(np root, u32 k) {
assert(!root || !root->p);
if (k == 0) return {nullptr, root};
if (k == (root->size)) return {root, nullptr};
splay_kth(root, k - 1);
np right = root->r;
root->r = nullptr, right->p = nullptr;
root->update();
return {root, right};
}
tuple<np, np, np> split3(np root, u32 l, u32 r) {
np nm, nr;
tie(root, nr) = split(root, r);
tie(root, nm) = split(root, l);
return {root, nm, nr};
}
tuple<np, np, np, np> split4(np root, u32 i, u32 j, u32 k) {
np d;
tie(root, d) = split(root, k);
auto [a, b, c] = split3(root, i, j);
return {a, b, c, d};
}
// 部分木が区間 [l,r) に対応するようなノードを作って返す
// そのノードが root になるわけではないので、
// このノードを参照した後にすぐに splay して根に持ち上げること
void goto_between(np &root, u32 l, u32 r) {
if (l == 0 && r == root->size) return;
if (l == 0) {
splay_kth(root, r);
root = root->l;
return;
}
if (r == root->size) {
splay_kth(root, l - 1);
root = root->r;
return;
}
splay_kth(root, r);
np rp = root;
root = rp->l;
root->p = nullptr;
splay_kth(root, l - 1);
root->p = rp;
rp->l = root;
rp->update();
root = root->r;
}
vc<X> get_all(const np &root) {
vc<X> res;
auto dfs = [&](auto &dfs, np root) -> void {
if (!root) return;
root->prop();
dfs(dfs, root->l);
res.eb(root->get());
dfs(dfs, root->r);
};
dfs(dfs, root);
return res;
}
X get(np &root, u32 k) {
assert(root == nullptr || !root->p);
splay_kth(root, k);
return root->get();
}
void set(np &root, u32 k, const X &x) {
assert(root != nullptr && !root->p);
splay_kth(root, k);
root->set(x);
}
void multiply(np &root, u32 k, const X &x) {
assert(root != nullptr && !root->p);
splay_kth(root, k);
root->multiply(x);
}
X prod(np &root, u32 l, u32 r) {
assert(root == nullptr || !root->p);
using Mono = typename Node::Monoid_X;
if (l == r) return Mono::unit();
assert(0 <= l && l < r && r <= root->size);
goto_between(root, l, r);
X res = root->prod;
splay(root, true);
return res;
}
X prod(np &root) {
assert(root == nullptr || !root->p);
using Mono = typename Node::Monoid_X;
return (root ? root->prod : Mono::unit());
}
void apply(np &root, u32 l, u32 r, const A &a) {
if (l == r) return;
assert(0 <= l && l < r && r <= root->size);
goto_between(root, l, r);
root->apply(a);
splay(root, true);
}
void apply(np &root, const A &a) {
if (!root) return;
root->apply(a);
}
void reverse(np &root, u32 l, u32 r) {
assert(root == nullptr || !root->p);
if (l == r) return;
assert(0 <= l && l < r && r <= root->size);
goto_between(root, l, r);
root->reverse();
splay(root, true);
}
void reverse(np root) {
if (!root) return;
root->reverse();
}
void rotate(Node *n) {
// n を根に近づける。prop, update は rotate の外で行う。
Node *pp, *p, *c;
p = n->p;
pp = p->p;
if (p->l == n) {
c = n->r;
n->r = p;
p->l = c;
} else {
c = n->l;
n->l = p;
p->r = c;
}
if (pp && pp->l == p) pp->l = n;
if (pp && pp->r == p) pp->r = n;
n->p = pp;
p->p = n;
if (c) c->p = p;
}
void prop_from_root(np c) {
if (!c->p) {
c->prop();
return;
}
prop_from_root(c->p);
c->prop();
}
void splay(Node *me, bool prop_from_root_done) {
// これを呼ぶ時点で、me の祖先(me を除く)は既に prop 済であることを仮定
// 特に、splay 終了時点で me は upd / prop 済である
if (!prop_from_root_done) prop_from_root(me);
me->prop();
while (me->p) {
np p = me->p;
np pp = p->p;
if (!pp) {
rotate(me);
p->update();
break;
}
bool same = (p->l == me && pp->l == p) || (p->r == me && pp->r == p);
if (same) rotate(p), rotate(me);
if (!same) rotate(me), rotate(me);
pp->update(), p->update();
}
// me の update は最後だけでよい
me->update();
}
void splay_kth(np &root, u32 k) {
assert(0 <= k && k < (root->size));
while (1) {
root->prop();
u32 sl = (root->l ? root->l->size : 0);
if (k == sl) break;
if (k < sl)
root = root->l;
else {
k -= sl + 1;
root = root->r;
}
}
splay(root, true);
}
// check(x), 左側のノード全体が check を満たすように切る
template <typename F>
pair<np, np> split_max_right(np root, F check) {
if (!root) return {nullptr, nullptr};
assert(!root->p);
np c = find_max_right(root, check);
if (!c) {
splay(root, true);
return {nullptr, root};
}
splay(c, true);
np right = c->r;
if (!right) return {c, nullptr};
right->p = nullptr;
c->r = nullptr;
c->update();
return {c, right};
}
// check(x, cnt), 左側のノード全体が check を満たすように切る
template <typename F>
pair<np, np> split_max_right_cnt(np root, F check) {
if (!root) return {nullptr, nullptr};
assert(!root->p);
np c = find_max_right_cnt(root, check);
if (!c) {
splay(root, true);
return {nullptr, root};
}
splay(c, true);
np right = c->r;
if (!right) return {c, nullptr};
right->p = nullptr;
c->r = nullptr;
c->update();
return {c, right};
}
// 左側のノード全体の prod が check を満たすように切る
template <typename F>
pair<np, np> split_max_right_prod(np root, F check) {
if (!root) return {nullptr, nullptr};
assert(!root->p);
np c = find_max_right_prod(root, check);
if (!c) {
splay(root, true);
return {nullptr, root};
}
splay(c, true);
np right = c->r;
if (!right) return {c, nullptr};
right->p = nullptr;
c->r = nullptr;
c->update();
return {c, right};
}
template <typename F>
np find_max_right(np root, const F &check) {
// 最後に見つけた ok の点、最後に探索した点
np last_ok = nullptr, last = nullptr;
while (root) {
last = root;
root->prop();
if (check(root->x)) {
last_ok = root;
root = root->r;
} else {
root = root->l;
}
}
splay(last, true);
return last_ok;
}
template <typename F>
np find_max_right_cnt(np root, const F &check) {
// 最後に見つけた ok の点、最後に探索した点
np last_ok = nullptr, last = nullptr;
ll n = 0;
while (root) {
last = root;
root->prop();
ll ns = (root->l ? root->l->size : 0);
if (check(root->x, n + ns + 1)) {
last_ok = root;
n += ns + 1;
root = root->r;
} else {
root = root->l;
}
}
splay(last, true);
return last_ok;
}
template <typename F>
np find_max_right_prod(np root, const F &check) {
using Mono = typename Node::Monoid_X;
X prod = Mono::unit();
// 最後に見つけた ok の点、最後に探索した点
np last_ok = nullptr, last = nullptr;
while (root) {
last = root;
root->prop();
X lprod = prod;
if (root->l) lprod = Mono::op(lprod, root->l->prod);
lprod = Mono::op(lprod, root->x);
if (check(lprod)) {
prod = lprod;
last_ok = root;
root = root->r;
} else {
root = root->l;
}
}
splay(last, true);
return last_ok;
}
};
#line 2 "/home/maspy/compro/library/ds/splaytree/splaytree_basic.hpp"
namespace SplayTreeNodes {
template <typename S>
struct Node_Basic {
using value_type = S;
using operator_type = int;
using np = Node_Basic *;
np p, l, r;
bool rev;
S x;
u32 size;
static void new_node(np n, const S &x) {
n->p = n->l = n->r = nullptr;
n->x = x, n->size = 1, n->rev = 0;
}
void update() {
size = 1;
if (l) { size += l->size; }
if (r) { size += r->size; }
}
void prop() {
if (rev) {
if (l) { l->rev ^= 1, swap(l->l, l->r); }
if (r) { r->rev ^= 1, swap(r->l, r->r); }
rev = 0;
}
}
// update, prop 以外で呼ばれるものは、splay 後であることが想定されている。
// したがってその時点で update, prop 済であることを仮定してよい。
S get() { return x; }
void set(const S &xx) {
x = xx;
update();
}
void reverse() {
swap(l, r);
rev ^= 1;
}
};
template <typename S>
using SplayTree_Basic = SplayTree<Node_Basic<S>>;
} // namespace SplayTreeNodes
using SplayTreeNodes::SplayTree_Basic;
#line 5 "main.cpp"
void solve() {
INT(N, Q);
vc<int> A(N);
FOR(i, N) A[i] = i;
SplayTree_Basic<int> ST(N);
using np = decltype(ST)::np;
np p = ST.new_node(A);
FOR(Q) {
INT(L, R);
--L;
ST.reverse(p, L, R);
}
A = ST.get_all(p);
for (auto& x: A) ++x;
print(A);
}
signed main() { solve(); }
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3680kb
input:
30 5 7 26 7 18 5 9 4 15 3 15
output:
1 2 4 17 16 15 6 5 18 19 20 21 22 23 3 24 25 26 14 13 12 11 10 9 8 7 27 28 29 30
result:
ok single line: '1 2 4 17 16 15 6 5 18 19 20 21...4 13 12 11 10 9 8 7 27 28 29 30'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3684kb
input:
100 10 9 29 10 68 7 72 15 73 57 79 4 39 11 69 45 61 1 42 15 21
output:
5 4 47 46 45 44 43 42 41 40 39 38 37 36 78 79 31 32 33 34 35 77 76 75 74 24 23 22 21 20 19 18 54 53 52 51 50 49 48 3 2 1 6 72 63 64 65 66 67 68 29 8 7 73 25 26 27 28 69 70 71 62 61 60 59 58 57 56 55 17 16 15 14 13 12 11 10 9 30 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
result:
ok single line: '5 4 47 46 45 44 43 42 41 40 39... 91 92 93 94 95 96 97 98 99 100'
Test #3:
score: 0
Accepted
time: 1ms
memory: 3864kb
input:
200 50 49 166 53 181 17 136 38 105 39 120 17 132 24 148 51 178 35 166 37 128 22 145 33 158 43 150 41 49 59 130 59 188 57 124 25 113 15 136 55 178 47 162 45 175 101 159 51 168 11 90 45 124 61 172 15 134 37 148 3 86 57 130 81 129 59 159 31 128 8 119 1 53 1 128 9 88 35 160 41 200 40 127 47 165 39 112 1...
output:
105 104 72 71 14 13 12 11 162 182 183 184 185 186 97 48 33 118 10 9 8 7 6 17 18 19 20 117 173 172 159 45 89 90 73 74 75 76 77 78 79 187 58 119 120 121 64 65 178 200 199 198 197 196 195 194 193 192 191 190 189 135 134 133 132 131 47 46 88 87 86 85 116 174 175 176 114 144 41 42 43 31 30 29 28 130 96 9...
result:
ok single line: '105 104 72 71 14 13 12 11 162 ... 32 166 165 164 163 181 180 179'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3684kb
input:
200 50 57 184 29 105 1 100 4 76 9 104 19 87 25 118 37 136 39 166 55 170 133 169 23 154 25 102 47 136 17 37 43 122 31 116 12 113 35 146 29 143 53 140 39 160 5 104 157 193 5 57 55 65 11 136 55 122 53 138 15 84 49 95 3 127 56 149 35 104 71 159 23 96 37 120 6 95 28 107 63 181 3 30 57 105 27 96 29 154 12...
output:
34 35 107 108 45 177 41 70 18 87 88 89 92 168 144 158 159 123 124 125 126 127 171 170 64 65 66 67 149 148 147 146 145 154 6 134 105 23 141 122 121 120 119 118 117 116 115 46 47 48 49 50 51 52 53 10 9 8 7 153 152 151 150 97 98 99 100 194 143 157 156 33 167 166 165 164 163 162 161 160 142 79 80 81 82 ...
result:
ok single line: '34 35 107 108 45 177 41 70 18 ...1 77 78 195 196 197 198 199 200'
Test #5:
score: 0
Accepted
time: 3ms
memory: 4120kb
input:
10000 3000 2766 8161 802 5794 623 6126 2879 8058 2011 8169 2017 9893 237 4761 3032 7817 838 4475 400 4961 241 1478 1957 6725 2245 5631 1519 5260 2189 5951 1585 7664 3098 8044 1809 6484 3127 8674 3126 6755 873 5942 105 5541 1685 5556 78 4452 3255 8289 537 5681 3 6305 4404 9793 548 5182 1000 5611 1821...
output:
8694 1445 8229 8230 8231 2838 2837 2836 2835 7220 7221 7222 7223 584 285 2924 515 739 740 741 742 743 9340 6210 6211 6212 8914 8913 8912 1994 5690 5691 5692 5693 5435 4580 4581 4582 4583 4584 4585 4586 4587 2028 4038 4037 4036 4181 9954 9955 3287 6066 6653 6652 6651 5031 5030 5029 5028 6582 6581 585...
result:
ok single line: '8694 1445 8229 8230 8231 2838 ... 9995 9996 9997 9998 9999 10000'
Test #6:
score: 0
Accepted
time: 60ms
memory: 5860kb
input:
50000 50000 5351 22924 23569 31837 10321 34305 24821 31124 7255 36650 9801 30062 27465 36441 6799 39256 12861 36908 19999 49816 38177 49281 4887 27918 13810 33483 8219 31074 1231 32512 12811 30950 31705 38376 12517 36898 9193 41418 6640 28721 3319 35161 14859 35985 8787 32188 81 18433 2859 28749 472...
output:
48014 26930 36546 1261 19039 41093 41094 9017 30509 14540 42177 3620 48562 34139 49910 28964 29701 9016 17610 49590 36985 17667 35860 18397 49199 39712 15509 24957 4982 453 454 455 9061 20463 38246 49225 29795 18827 18828 5060 13133 33917 30100 39575 20799 48246 48245 21475 38732 21765 29762 23049 5...
result:
ok single line: '48014 26930 36546 1261 19039 4...8614 8615 15358 2597 2598 50000'
Test #7:
score: 0
Accepted
time: 109ms
memory: 7504kb
input:
80000 70000 5639 33189 58689 76401 22323 63782 9379 60566 24044 65425 26023 71449 7993 61134 19089 64394 11624 49545 54470 72393 15679 50852 12239 42684 18293 57292 6893 44628 19100 61605 6111 38496 7615 60504 4047 38342 8735 60458 11602 61623 4837 51608 56131 66851 44401 75157 14135 42318 15677 510...
output:
60666 41986 49896 20550 5704 5705 5706 10915 35225 23036 23037 67036 67037 36041 11205 31611 76382 21038 29429 70674 70673 35560 36629 36628 34587 51651 21187 29365 22356 27638 68982 68983 68984 33197 53012 13558 21168 79338 79339 79340 71899 5753 54124 59519 15893 2101 61797 77780 14668 60916 44254...
result:
ok single line: '60666 41986 49896 20550 5704 5...9 52749 78001 61574 79999 80000'
Test #8:
score: 0
Accepted
time: 182ms
memory: 8356kb
input:
100000 100000 26201 76499 2133 49270 16969 54134 20129 81465 30309 95715 16450 75674 31087 95302 25186 63359 28653 85166 33110 72970 2773 55409 10286 68395 53815 86337 304 61183 27663 88134 17939 66827 28395 88990 17457 98881 958 55658 17527 57075 19575 69265 4019 47133 48549 59998 16148 54577 12091...
output:
48382 82046 57881 9235 76677 33462 84995 83053 8060 82151 82152 63534 63535 48529 61112 7695 22575 31032 52215 39360 6022 33089 3260 42656 58062 79509 83713 19526 18576 21796 28655 28654 84107 8663 68055 24698 24697 29016 29017 52336 23602 4974 32300 89077 82078 65138 71972 59397 56986 69328 26439 5...
result:
ok single line: '48382 82046 57881 9235 76677 3... 98311 26991 26992 58731 100000'
Test #9:
score: 0
Accepted
time: 175ms
memory: 8336kb
input:
100000 100000 89003 90209 46083 96417 23507 88692 24354 68519 14791 58309 937 56827 8485 74848 25853 79517 5262 70656 4118 54651 980 52207 25265 70914 31713 90674 545 40408 29188 77333 10967 69263 15841 57641 5223 46419 23905 70366 383 59463 28161 94766 26005 68202 15775 59971 32578 92749 24170 6505...
output:
44538 59025 59600 24875 87550 32120 32121 96880 35553 23105 46839 71441 65830 87344 67098 25193 10833 34147 35461 56271 88328 52956 39722 52742 71452 63088 63089 46633 46632 46631 33087 32623 32622 32621 90948 10909 87520 4356 25063 61766 89391 99065 34630 28669 94972 99221 31212 35311 89976 34897 6...
result:
ok single line: '44538 59025 59600 24875 87550 ... 45224 75512 99998 99999 100000'
Test #10:
score: 0
Accepted
time: 182ms
memory: 8328kb
input:
100000 100000 4087 54523 35889 83701 29237 63069 13324 54160 66297 71875 2063 82484 24510 85797 17796 40115 6656 67026 30611 64488 75085 82245 4003 58692 62333 88273 4706 42110 18680 73012 9242 67838 2497 35928 27556 78883 27622 85762 33271 94733 27115 79171 5601 52585 10950 74087 22029 81150 90337 ...
output:
99318 20129 52948 52947 4068 47045 82589 82588 57020 57021 65919 32841 88592 3956 9346 72561 54657 37672 99925 48134 93660 88805 88806 70239 43192 84763 57016 57015 57014 2249 70962 68269 99523 99522 99521 92142 92143 51961 47914 92784 34096 34097 40316 30416 87491 87492 30115 72921 3506 3507 29634 ...
result:
ok single line: '99318 20129 52948 52947 4068 4... 22295 22294 22293 99999 100000'