今天模拟赛脑子抽了三维偏序写个树套树,然后爆零了,然后我开始调,然后一下午没了。问了队爷lch他也没找出来错/kk 。麻烦各位有时间的帮忙看一下树套树哪里有问题qwq。
ps 已经用暴力验证过式子没有问题。
#include <cstdio>
#include <algorithm>
const int N = 1e6 + 10;
struct D2_Tree
{
#define Ls(x) (node[x].son[0])
#define Rs(x) (node[x].son[1])
#define Fa(x) (node[x].fa)
struct Splay{ int fa, son[2], val, size, cnt; }node[N << 2];
int rt[N << 2], tot;
void pushup(int x)
{ node[x].size = node[Ls(x)].size + node[Rs(x)].size + node[x].cnt; }
int get(int x) { return Rs(Fa(x)) == x; }
void rotate(int x)
{
int fa = Fa(x), gf = Fa(fa), d = get(x), dd = get(fa);
node[fa].son[d] = node[x].son[d ^ 1]; Fa(node[x].son[d ^ 1]) = fa;
node[x].son[d ^ 1] = fa; Fa(fa) = x; Fa(x) = gf;
if (gf) node[gf].son[dd] = x;
pushup(fa); pushup(x);
}
void splay(int& root, int x)
{
for (int fa; fa = Fa(x); rotate(x))
if (Fa(fa)) rotate(get(fa) == get(x) ? fa : x);
root = x;
}
void ins(int& root, int val)
{
int x = root, fa = 0;
while (x && node[x].val != val)
{
fa = x;
x = node[x].son[node[x].val < val];
}
if (x) node[x].cnt++, ++node[x].size;
else
{
node[x = ++tot].val = val; node[x].fa = fa;
node[x].size = node[x].cnt = 1;
Ls(x) = Rs(x) = 0;
}
splay(root, x);
}
int get_rank(int& root, int val)
{
int x = root, rk = 0;
while (x)
{
if (node[x].val > val) x = Ls(x);
else if (node[x].val == val)
{
rk += node[Ls(x)].size;
splay(root, x); return rk;
}
else rk += node[Ls(x)].size + node[x].cnt, x = Rs(x);
}
return rk;
}
int get_cnt(int& root, int val)
{
int x = root;
while (x)
{
if (node[x].val > val) x = Ls(x);
else if (node[x].val == val)
{ splay(root, x); return node[x].cnt; }
else x = Rs(x);
}
return 0;
}
void add(int k, int l, int r, int x, int v)
{
ins(rt[k], v);
if (l == r) return ;
int mid = l + r >> 1;
if (x <= mid) add(k << 1, l, mid, x, v);
else add(k << 1 | 1, mid + 1, r, x, v);
}
int query_rank(int k, int l, int r, int x, int y, int v)
{
if (x <= l && r <= y) return get_rank(rt[k], v);
int mid = l + r >> 1, ret = 0;
if (x <= mid) ret += query_rank(k << 1, l, mid, x, y, v);
if (mid < y) ret += query_rank(k << 1 | 1, mid + 1, r, x, y, v);
return ret;
}
int query_cnt(int k, int l, int r, int x, int y, int v)
{
if (x <= l && r <= y) return get_cnt(rt[k], v);
int mid = l + r >> 1, ret = 0;
if (x <= mid) ret += query_cnt(k << 1, l, mid, x, y, v);
if (mid < y) ret += query_cnt(k << 1 | 1, mid + 1, r, x, y, v);
return ret;
}
#undef Ls
#undef Rs
#undef Fa
}tree1, tree2;
struct Q{ int l, r, typ, t, pos; }q[N];
int tmp[N << 2], tp, eid;
inline int getid(int val)
{
int l = 1, r = eid, mid;
while (l < r)
{
mid = l + r >> 1;
if (tmp[mid] == val) return mid;
if (tmp[mid] < val) l = mid + 1;
else r = mid - 1;
}
return l;
}
int main()
{
freopen("mind.in", "r", stdin); freopen("mind.out", "w", stdout);
int n; scanf("%d", &n); char opt[5];
for (int i = 1; i <= n; i++)
{
scanf("%s%d", opt, &q[i].pos);
if (opt[0] == 'T')
scanf("%d", &q[i].t), q[i].typ = 1,
tmp[++tp] = q[i].pos, tmp[++tp] = q[i].pos - q[i].t, tmp[++tp] = q[i].pos + q[i].t;
else
{
scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].t); q[i].typ = 2;
tmp[++tp] = q[i].pos - q[i].t; tmp[++tp] = q[i].pos + q[i].t;
tmp[++tp] = q[i].l; tmp[++tp] = q[i].r;
}
}
std::sort(tmp + 1, tmp + 1 + tp);
eid = std::unique(tmp + 1, tmp + tp + 1) - tmp - 1;
for (int i = 1, l, r, pos, t1, t2, t3; i <= n; i++)
{
if (q[i].typ == 1)
{
pos = getid(q[i].pos);
tree1.add(1, 1, eid, pos, getid(q[i].pos - q[i].t));
tree2.add(1, 1, eid, pos, getid(q[i].pos + q[i].t));
}
else
{
l = getid(q[i].l), r = getid(q[i].r);
printf("%d\n", -tree2.query_rank(1, 1, eid, l, r, getid(q[i].pos - q[i].t)) +
tree1.query_rank(1, 1, eid, l, r, getid(q[i].pos + q[i].t)) +
tree1.query_cnt(1, 1, eid, l, r, getid(q[i].pos + q[i].t)));
}
}
return 0;
}