#include <bits/stdc++.h>
#define int long long
#define MAX 6000
#define MAX_Q 3000000
#define INF 2000000000
using namespace std;
struct Line {
int A, B;
int get(int X) { return A * X + B; }
Line(int A, int B) : A(A), B(B) {}
};
struct Node {
int l = -1, r = -1, s, e;
Line line;
Node(int s, int e, Line line) : s(s), e(e), line(line) {}
};
class LiChaoTree {
private:
void update(int n, Line v) {
int s = tree[n].s, e = tree[n].e;
Line low = tree[n].line, high = v;
if (low.get(s) > high.get(s))
swap(low, high);
if (low.get(e) <= high.get(e)) {
tree[n].line = high;
return;
}
if (low.get(s + e >> 1) < high.get(s + e >> 1)) {
tree[n].line = high;
if (tree[n].r == -1) {
tree[n].r = tree.size();
tree.push_back(Node((s + e >> 1) + 1, e, Line(0, 0)));
}
update(tree[n].r, low);
} else {
tree[n].line = low;
if (tree[n].l == -1) {
tree[n].l = tree.size();
tree.push_back(Node(s, (s + e >> 1), Line(0, 0)));
}
update(tree[n].l, high);
}
}
int query(int n, int x) {
if (n == -1)
return 0;
int s = tree[n].s, e = tree[n].e;
if (x <= s + e >> 1)
return max(tree[n].line.get(x), query(tree[n].l, x));
return max(tree[n].line.get(x), query(tree[n].r, x));
}
public:
vector<Node> tree;
void init(int s, int e) {
tree.push_back(Node(s, e, Line(0, 0)));
}
LiChaoTree(int s, int e) { init(s, e); }
void update(Line v) { update(0, v); }
int query(int x) { return query(0, x); }
};
int T[MAX], A[MAX], B[MAX], C[MAX], dp[MAX][MAX], val[MAX][MAX][2], P[MAX_Q], K[MAX_Q], V[MAX_Q][2], ans[MAX_Q];
vector<int> arr[MAX][MAX];
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int N, Q, X, Y, Z, Xs, Ys, XT, YT;
vector<int> Xcomp, Ycomp;
cin >> N >> Q;
for (int i = 1; i <= N; i++) {
cin >> T[i] >> A[i] >> B[i] >> C[i], C[i] /= 2;
Xcomp.push_back(A[i] + T[i]), Ycomp.push_back(-A[i] + T[i]);
if (A[i] <= B[i])
Xcomp.push_back(B[i] * 2 - A[i] + T[i]);
else
Ycomp.push_back(-B[i] * 2 + A[i] + T[i]);
}
sort(Xcomp.begin(), Xcomp.end()), Xcomp.erase(unique(Xcomp.begin(), Xcomp.end()), Xcomp.end()), Xs = Xcomp.size();
sort(Ycomp.begin(), Ycomp.end()), Ycomp.erase(unique(Ycomp.begin(), Ycomp.end()), Ycomp.end()), Ys = Ycomp.size();
for (int i = 1; i <= N; i++) {
if (A[i] <= B[i]) {
X = lower_bound(Xcomp.begin(), Xcomp.end(), A[i] + T[i]) - Xcomp.begin() + 1;
Y = lower_bound(Xcomp.begin(), Xcomp.end(), B[i] * 2 - A[i] + T[i]) - Xcomp.begin() + 1;
Z = lower_bound(Ycomp.begin(), Ycomp.end(), -A[i] + T[i]) - Ycomp.begin() + 1;
for (int j = X; j < Y; j++)
val[j][Z][0] = max(val[j][Z][0], C[i]);
} else {
X = lower_bound(Ycomp.begin(), Ycomp.end(), -A[i] + T[i]) - Ycomp.begin() + 1;
Y = lower_bound(Ycomp.begin(), Ycomp.end(), -B[i] * 2 + A[i] + T[i]) - Ycomp.begin() + 1;
Z = lower_bound(Xcomp.begin(), Xcomp.end(), A[i] + T[i]) - Xcomp.begin() + 1;
for (int j = X; j < Y; j++)
val[Z][j][1] = max(val[Z][j][1], C[i]);
}
}
for (int i = Xs; i >= 1; i--)
for (int j = Ys; j >= 1; j--) {
X = 0, Y = 0;
if (i < Xs)
X = dp[i + 1][j] + val[i][j][0] * (Xcomp[i] - Xcomp[i - 1]);
if (j < Ys)
Y = dp[i][j + 1] + val[i][j][1] * (Ycomp[j] - Ycomp[j - 1]);
dp[i][j] = max(X, Y);
}
for (int i = 1; i <= Q; i++) {
cin >> X >> Y;
P[i] = lower_bound(Xcomp.begin(), Xcomp.end(), X + Y) - Xcomp.begin() + 1;
V[i][0] = P[i] <= Xcomp.size() ? (Xcomp[P[i] - 1] - X - Y) : 0;
K[i] = lower_bound(Ycomp.begin(), Ycomp.end(), X - Y) - Ycomp.begin() + 1;
V[i][1] = K[i] <= Ycomp.size() ? (Ycomp[K[i] - 1] - X + Y) : 0;
arr[P[i]][K[i]].push_back(i);
}
LiChaoTree lichao(0, INF);
for (int i = 1; i <= Xs; i++) {
lichao.tree.clear(), lichao.init(0, INF);
for (int j = Ys; j >= 1; j--) {
lichao.update(Line(val[i - 1][j][0], dp[i][j]));
for (int k : arr[i][j])
ans[k] = max(ans[k], lichao.query(V[k][0]));
}
}
for (int i = 1; i <= Ys; i++) {
lichao.tree.clear(), lichao.init(0, INF);
for (int j = Xs; j >= 1; j--) {
lichao.update(Line(val[j][i - 1][1], dp[j][i]));
for (int k : arr[j][i])
ans[k] = max(ans[k], lichao.query(V[k][1]));
}
}
for (int i = 1; i <= Q; i++)
cout << ans[i] << '\n';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |