问题:
#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;
}