20pts求调
查看原帖
20pts求调
364848
Bodhi楼主2024/3/4 23:17

RT,#1~10全WA

记录

#include <bits/stdc++.h>
using namespace std;

const int R = 5e4 + 10;
struct Point
{
	int pos[3];
	bool operator==(const Point &oth) const
	{
		for (int i = 0; i < 3; ++i)
		{
			if (pos[i] ^ oth.pos[i])
			{
				return false;
			}
		}
		return true;
	}
} a[R];
struct _4D
{
	int pos[4];
	bool operator<(const _4D &oth) const
	{
		for (int i = 0; i < 4; ++i)
		{
			if (pos[i] ^ oth.pos[i])
			{
				return pos[i] < oth.pos[i];
			}
		}
		return false;
	}
} b[R];
struct Node
{
	int son[2], mn[3], mx[3], val, res; // 这种做完之后尝试一下leafy式的结构,虽然树高多一层,但是位运算快
	Point now;
	Node()
	{
		mn[0] = mn[1] = mn[2] = INT_MAX;
		mx[0] = mx[1] = mx[2] = INT_MIN;
	}
} t[R];
#define lc(k) t[k].son[0]
#define rc(k) t[k].son[1]
int tot, f[R]; // 使用f优化掉一维,不用f的话直接n次取最大
void pushup(int k)
{
	t[k].res = max({t[lc(k)].res, t[rc(k)].res, t[k].val});
}
void pushup_pos(int k) // update的时候不需要更新,所以这部分直接分离出来
{
	for (int i = 0; i < 3; ++i)
	{
		t[k].mn[i] = t[k].mx[i] = t[k].now.pos[i];
		if (lc(k))
		{
			t[k].mn[i] = min(t[k].mn[i], t[lc(k)].mn[i]);
			t[k].mx[i] = max(t[k].mx[i], t[lc(k)].mx[i]);
		}
		if (rc(k))
		{
			t[k].mn[i] = min(t[k].mn[i], t[rc(k)].mn[i]);
			t[k].mx[i] = max(t[k].mx[i], t[rc(k)].mx[i]);
		}
	}
}
int build(int l, int r, int kd)
{
	if (l > r)
	{
		return 0;
	}
	int mid = (l + r) >> 1, k = ++tot;
	nth_element(a + l, a + mid, a + r + 1, [&](Point x, Point y)
				{ return x.pos[kd] < y.pos[kd]; });
	t[k].now = a[mid];
	t[k].val = 0;
	lc(k) = build(l, mid - 1, (kd + 1) % 3);
	rc(k) = build(mid + 1, r, (kd + 1) % 3);
	pushup_pos(k);
	return k;
}
int query(int k, Point p)
{
	if (!k || t[k].mn[0] > p.pos[0] || t[k].mn[1] > p.pos[1] || t[k].mn[2] > p.pos[2])
	{
		return -1;
	}
	if (t[k].mx[0] <= p.pos[0] && t[k].mx[1] <= p.pos[1] && t[k].mx[2] <= p.pos[2])
	{
		return t[k].res;
	}
	int res = -1;
	if (t[k].now.pos[0] <= p.pos[0] && t[k].now.pos[1] <= p.pos[1] && t[k].now.pos[2] <= p.pos[2])
	{
		res = t[k].val;
	}
	res = max({res, query(lc(k), p), query(rc(k), p)});
	return res;
}
void update(int k, Point p, int val)
{
	if (!k ||
		t[k].mn[0] > p.pos[0] || t[k].mx[0] < p.pos[0] ||
		t[k].mn[1] > p.pos[1] || t[k].mx[1] < p.pos[1] ||
		t[k].mn[2] > p.pos[2] || t[k].mx[2] < p.pos[2])
	{
		return;
	}
	if (t[k].now == p)
	{
		t[k].val = max(val, t[k].val); //
		pushup(k);
		return;
	}
	// if (t[k].now.pos[kd] < p.pos[kd])//疑惑1
	// {
	update(lc(k), p, val);
	// }
	// else
	// {
	update(rc(k), p, val);
	// }
	pushup(k);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n, i, ans = -1;
	cin >> n;
	for (i = 1; i <= n; ++i)
	{
		cin >> b[i].pos[0] >> b[i].pos[1] >> b[i].pos[2] >> b[i].pos[3];
	}
	sort(b + 1, b + n + 1);
	for (i = 1; i <= n; ++i)
	{
		a[i].pos[0] = b[i].pos[1];
		a[i].pos[1] = b[i].pos[2];
		a[i].pos[2] = b[i].pos[3];
	}
	build(1, n, 0);
	for (i = 1; i <= n; ++i)
	{
		f[i] = max(query(1, a[i]), 0) + 1; // 在这个点之前有多少个<=当前点的点
		ans = max(ans, f[i]);
		update(1, a[i], f[i]);
	}
	cout << ans << flush;
	return 0;
}

2024/3/4 23:17
加载中...