为什么写出来的二维线段树(树套树)很有问题呢,哪位大佬帮忙挑一挑呀,赏 3 关注
查看原帖
为什么写出来的二维线段树(树套树)很有问题呢,哪位大佬帮忙挑一挑呀,赏 3 关注
936147
Pigsyy楼主2023/8/17 13:09

问题:

  1. WA
  2. MLE

Code

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int SIZE = 1e3 + 10;

int N, M;
std::vector<vector<int>> f(SIZE + 1, vector<int>(SIZE + 1, 1e18));
std::vector<int> L1(SIZE + 1), R1(SIZE + 1), L2(SIZE + 1), R2(SIZE + 1), W(SIZE + 1);

struct Node_Y
{
	int l, r;
	int Min;	
};
struct Segment_Y
{
	Node_Y Tree_Y[4005];
	void Pushup(int u)
	{
		Tree_Y[u].Min = min(Tree_Y[u << 1].Min, Tree_Y[u << 1 | 1].Min);
	}
	void Build(int u, int l, int r)
	{
		Tree_Y[u] = {l, r, (int)1e18};
		if (l == r)
			return;
		int mid = l + r >> 1;
		Build(u << 1, l, mid), Build(u << 1 | 1, mid + 1, r);
		Pushup(u);
	}
	void Modify(int u, int y, int d)
	{
		if (Tree_Y[u].l == Tree_Y[u].r && Tree_Y[u].l == y)
			Tree_Y[u].Min = d;
		else
		{
			int mid = Tree_Y[u].l + Tree_Y[u].r >> 1;
			if (mid >= y) Modify(u << 1, y, d);
			else Modify(u << 1 | 1, y, d);
			Pushup(u);
		}
	}
	int Query(int u, int l, int r)
	{
		if (Tree_Y[u].l >= l && Tree_Y[u].r <= r)
			return Tree_Y[u].Min;
		int mid = Tree_Y[u].l + Tree_Y[u].r >> 1;
		if (mid >= r) return Query(u << 1, l, r);
		else if (l > mid) return Query(u << 1 | 1, l, r);
		else return min(Query(u << 1, l, mid), Query(u << 1 | 1, mid + 1, r));
	}
};
struct Node_X
{
	int l, r;
	Segment_Y Y;
};
struct Segment_X
{
	Node_X Tree_X[4005];
	void Build(int u, int l, int r)
	{
		Tree_X[u] = {l, r};
		Tree_X[u].Y.Build(1, 1, M);
		if (l == r) return;
		int mid = l + r >> 1;
		Build(u << 1, l, mid), Build(u << 1 | 1, mid + 1, r);
	}
	void Modify(int u, int x, int y, int d)
	{
		Tree_X[u].Y.Modify(1, y, d);
		if (Tree_X[u].l == Tree_X[u].r) return;
		else
		{
			int mid = Tree_X[u].l + Tree_X[u].r >> 1;
			if (mid >= x) Modify(u << 1, x, y, d);
			else Modify(u << 1 | 1, x, y, d);
		}
	}
	int Query(int u, int lx, int ly, int rx, int ry)
	{
		if (Tree_X[u].l >= lx && Tree_X[u].r <= rx)
			return Tree_X[u].Y.Query(1, ly, ry);
		int mid = Tree_X[u].l + Tree_X[u].r >> 1;
		if (rx <= mid) return Query(u << 1, lx, ly, rx, ry);
		else if (lx > mid) return Query(u << 1 | 1, lx, ly, rx, ry);
		else return min(Query(u << 1, lx, ly, mid, ry), Query(u << 1 | 1, mid + 1, ly, rx, ry));
	}
};
Segment_X Tree;

signed main()
{
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	cin >> N;
	M = N;

	for (int i = 1; i <= N; i ++)
		cin >> L1[i];

	for (int i = 1; i <= N; i ++)
		cin >> R1[i];

	for (int i = 1; i <= N; i ++)
		cin >> L2[i];

	for (int i = 1; i <= N; i ++)	
		cin >> R2[i];

	for (int i = 1; i <= N; i ++)
		cin >> W[i];

	Tree.Build(1, 1, N);

	f[1][1] = 0;
	Tree.Modify(1, 1, 1, W[1] + W[1] - 2);
	for (int i = 2; i <= N; i ++)
		for (int j = 2; j <= N; j ++)
		{
			if (R1[i] == 0 || R2[j] == 0 || L1[i] > R1[i] || L2[j] > R2[j])
			{
				f[i][j] = 1e18;
				continue;
			}
			int Result = Tree.Query(1, max(1ll, L1[i]), max(1ll, L2[j]), R1[i], R2[j]);
			f[i][j] = min(f[i][j], Result + W[i] + W[j] - i - j);
			Tree.Modify(1, i, j, f[i][j] + W[i] + W[j] - i - j);
		}

	for (int i = 1; i <= N; i ++)
	{
		for (int j = 1; j <= N; j ++)
			if (f[i][j] >= 1e18 / 2)
				cout << "inf ";
			else
				cout << f[i][j] << " ";
		cout << endl;
	}

	return 0;
}
2023/8/17 13:09
加载中...