#define int int
#define intd "%d"
namespace PPP {
#define tl template
#define cu const unsigned
template<cu __memory_size, cu __root_size> class manyset {
private:
struct node {
int cnt, l, r, f;
node() {
cnt = l = r = f = 0;
}
} t[__memory_size];
int root[__root_size], frt, rtf, min, max;
int newnode() {
t[++frt] = node();
return frt;
}
/*递归*/ void merge(int p, int q, int l, int r) {
if(l == r)
return t[p].cnt += t[q].cnt, t[q] = node(), void();
int mid = l + r >> 1;
if(t[p].l != 0 && t[q].l != 0)
merge(t[p].l, t[q].l, l, mid);
else if(t[q].l != 0)
t[p].l = t[q].l, t[q].l = 0, t[t[p].l].f = p;
if(t[p].r != 0 && t[q].r != 0)
merge(t[p].r, t[q].r, mid + 1, r);
else if(t[q].r != 0)
t[p].r = t[q].r, t[q].r = 0, t[t[p].r].f = p;
t[p].cnt = t[t[p].l].cnt + t[t[p].r].cnt, t[q] = node();
}
public:
int newset() {
root[++rtf] = newnode();
return rtf;
}
/*迭代*/ void modify(int p, int k, int v) {
int now = root[p], l = min, r = max,
mid = l + r >> 1;
while(l != r)
if(k <= mid) {
r = mid, mid = l + r >> 1;
if(t[now].l == 0)
t[now].l = newnode(),
t[t[now].l].f = now;
now = t[now].l;
} else {
l = mid + 1, mid = l + r >> 1;
if(t[now].r == 0)
t[now].r = newnode(),
t[t[now].r].f = now;
now = t[now].r;
}
t[now].cnt += v;
while(now != root[p])
t[t[now].f].cnt += v, now = t[now].f;
}
/*迭代*/ int query(int p, int k) {
if(k == 0)
return 0;
int now = root[p], l = min, r = max,
mid = l + r >> 1, res = 0;
while(l != r)
if(k <= mid) {
r = mid, mid = l + r >> 1;
if(t[now].l == 0)
return res;
else
now = t[now].l;
} else {
l = mid + 1, mid = l + r >> 1,
res += t[t[now].l].cnt,
now = t[now].r;
if(t[now].r == 0)
return res;
}
res += t[now].cnt;
return res;
}
/*迭代*/ int find(int p, int k) {
if(t[root[p]].cnt < k)
return -1;
int now = root[p], l = min, r = max,
mid = l + r >> 1;
while(l != r)
if(k <= t[t[now].l].cnt)
r = mid, mid = l + r >> 1,
now = t[now].l;
else
l = mid + 1, mid = l + r >> 1,
k -= t[t[now].l].cnt,
now = t[now].r;
return l;
}
/*迭代*/ void split(int p, int q, int k) {
int now = root[p], newnow = root[q],
l = min, r = max, mid = l + r >> 1;
while(l != r)
if(k < mid) {
r = mid, mid = l + r >> 1,
t[newnow].r = t[now].r, t[now].r = 0, t[t[newnow].r].f = newnow;
if(t[now].l == 0)
if(t[newnow].r == 0)
break;
else {
t[newnow].cnt = t[t[newnow].l].cnt + t[t[newnow].r].cnt;
break;
}
t[newnow].l = newnode(),
t[t[newnow].l].f = newnow,
newnow = t[newnow].l,
now = t[now].l;
} else if(k > mid) {
l = mid + 1, mid = l + r >> 1;
if(t[now].r == 0)
break;
t[newnow].r = newnode(),
t[t[newnow].r].f = newnow,
newnow = t[newnow].r,
now = t[now].r;
} else if(k == mid) {
t[newnow].r = t[now].r, t[now].r = 0, t[t[newnow].r].f = newnow;
break;
}
now = t[now].f, newnow = t[newnow].f;
while(now != root[p])
t[now].cnt = t[t[now].l].cnt + t[t[now].r].cnt,
t[newnow].cnt = t[t[newnow].l].cnt + t[t[newnow].r].cnt,
now = t[now].f, newnow = t[newnow].f;
}
void merge(int p, int q) {
return merge(root[p], root[q], min, max);
}
manyset<__memory_size, __root_size>(int G, int H) {
min = G, max = H;
t[0] = node(), frt = rtf = 0,
root[++rtf] = newnode();
}
};
#undef tl
#undef cu
}
using namespace PPP;
#define scanf __builtin_scanf
#define printf __builtin_printf
int n, m;
manyset<4194304, 262144> f(1, 262144);
signed main() {
scanf(intd intd, &n, &m);
for(int i = 1, a; i <= n; i++)
scanf(intd, &a), f.modify(1, i, a);
while(m--) {
int oper, p, q, x, y;
scanf(intd, &oper);
switch(oper) {
case 0:
scanf(intd intd intd, &p, &x, &y), q = f.newset(),
f.split(p, q, x - 1), f.split(q, 0, y), f.merge(p, 0);
break;
case 1:
scanf(intd intd, &p, &q), f.merge(p, q);
break;
case 2:
scanf(intd intd intd, &p, &x, &y), f.modify(p, y, x);
break;
case 3:
scanf(intd intd intd, &p, &x, &y),
printf(intd " " intd "\n", f.query(p, y), f.query(p, x - 1));
break;
case 4:
scanf(intd intd, &p, &x),
printf(intd "\n", f.find(p, x));
break;
}
}
return 0;
}
#undef int
#undef intd
#undef scanf
#undef printf
头文件吃了
如题,错误很可能在在 manyset::split()
或 manyset::merge()
上,求查错
f
表示父节点
码风等勿喷