蹲一个有时间的大佬帮忙调树套树qwq
  • 板块学术版
  • 楼主zhiyangfanshotacon
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/8/6 17:38
  • 上次更新2023/11/4 11:48:11
查看原帖
蹲一个有时间的大佬帮忙调树套树qwq
137603
zhiyangfanshotacon楼主2021/8/6 17:38

今天模拟赛脑子抽了三维偏序写个树套树,然后爆零了,然后我开始调,然后一下午没了。问了队爷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;
}
2021/8/6 17:38
加载中...