最好是 n≤20 的,虽然我找不到这样的数据
#include <algorithm>
#include <cstdio>
#include <random>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
mt19937 Rand;
struct Vertex {
ll val, sum;
int siz, cnt;
bool vis;
unsigned rank;
Vertex *son[2];
Vertex(const ll &__val = 0) {
sum = val = __val;
rank = Rand();
vis = 0;
siz = cnt = 1;
son[0] = son[1] = nullptr;
}
void Copy(Vertex *p) { p && (*this = *p, 1); }
} *rt[maxn];
int siz(Vertex *p) { return p ? p->siz : 0; }
ll sum(Vertex *p) { return p ? p->sum : 0; }
void Pushup(Vertex *p) {
if (p)
p->siz = siz(*p->son) + siz(p->son[1]) + p->cnt, p->sum = sum(*p->son) + sum(p->son[1]) + p->val;
}
void Maintain(Vertex *p) {
if (p) {
Vertex *x = new Vertex();
x->Copy(p), p = x;
}
}
void TagRev(Vertex *p) {
if (p) p->vis ^= 1;
}
void Pushdown(Vertex *p) {
if (p && p->vis)
Maintain(*p->son), Maintain(p->son[1]), swap(*p->son, p->son[1]), TagRev(*p->son), TagRev(p->son[1]), p->vis = 0;
}
void SplitRank(const ll &k, Vertex *&u, Vertex *&v, Vertex *p) {
if (!p) return void(u = v = nullptr);
Pushdown(p);
if (k <= siz(p->son[0])) {
v = new Vertex();
v->Copy(p);
SplitRank(k, u, v->son[0], v->son[0]);
Pushup(v);
}
else {
u = new Vertex();
u->Copy(p);
SplitRank(k - siz(p->son[0]) - p->cnt, u->son[1], v, u->son[1]);
Pushup(u);
}
}
void Merge(Vertex *u, Vertex *v, Vertex *&p) {
if (!u || !v) return void(p = u ? u : v);
p = new Vertex;
Pushdown(u);
Pushdown(v);
if (u->rank >= v->rank) {
p->Copy(v);
Merge(u, p->son[0], p->son[0]);
}
else {
p->Copy(u);
Merge(p->son[1], v, p->son[1]);
}
Pushup(p);
}
void Update(const ll &k, const ll &x, Vertex *u, Vertex *&v) {
Vertex *a = nullptr, *b = nullptr, *c = nullptr;
SplitRank(k, a, c, u);
b = new Vertex{x};
Merge(b, c, b);
Merge(a, b, v);
}
void Erase(const ll &k, Vertex *u, Vertex *&v) {
Vertex *a = nullptr, *b = nullptr, *c = nullptr;
SplitRank(k - 1, a, b, u), SplitRank(1, b, c, b);
if (b) {
delete b;
b = nullptr;
}
Merge(a, c, v);
}
void Reverse(const ll &l, const ll &r, Vertex *u, Vertex *&v) {
Vertex *a = nullptr, *b = nullptr, *c = nullptr;
SplitRank(l - 1, a, b, u);
SplitRank(r - l + 1, b, c, b);
TagRev(b);
Merge(b, c, b);
Merge(a, b, v);
}
ll Get(const ll &l, const ll &r, Vertex *u, Vertex *&v) {
Vertex *a = nullptr, *b = nullptr, *c = nullptr;
SplitRank(l - 1, a, b, u);
SplitRank(r - l + 1, b, c, b);
ll reply = sum(b);
Merge(b, c, b);
Merge(a, b, v);
return reply;
}
int main() {
int n;
scanf("%d", &n);
ll last = 0, x, p;
for (int i = 1, tp, v; i <= n; ++i) {
scanf("%d%d%lld", &v, &tp, &p);
p ^= last;
if (tp == 2) Erase(p, rt[v], rt[i]);
else {
scanf("%lld", &x), x ^= last;
if (tp == 1) Update(p, x, rt[v], rt[i]);
else if (tp == 3) Reverse(p, x, rt[v], rt[i]);
else printf("%lld", last = Get(p, x, rt[v], rt[i])), putchar(10);
}
}
return 0;
}