JZOJ4559 【NOI2016模拟6.23】水平线上的肮脏交易和卑鄙勾当 转换模型后CDQ分治
题目大意
现在有一个坐标轴,现在有 N 个交易。对于一个交易有发生的时间
−106≤si≤106
解题思路
我们考虑交易 j 满足什么条件时能在事件
移一下项得:
tj+sj≥si+titj−sj≥ti−si
那么对于每个交易 j 我们只需要维护
把第 i 个交易在线段树中的下标为
程序
//YxuanwKeith
#include
#include
#include using namespace std;const int MAXN = 4e6 + 5, MAXM = 1e5 + 5;
const int Inf = 1e9 + 7;struct Node {int x, y, t;Node (int a, int b, int c) {x = a, y = b, t = c;}Node () {}
};struct Tree {int l, r, MaxT, MinF;
} Tr[MAXN * 4];Node D[MAXM], G[MAXM];
int N, T, Lim, End, Root, tot, F[MAXM];bool CmpX(Node A, Node B) {return A.x < B.x || A.x == B.x && A.y > B.y;
}bool CmpY(Node A, Node B) {return A.y > B.y || A.y == B.y && A.x < B.x;
}void Clear(int Now) {Tr[Now].l = Tr[Now].r = 0;Tr[Now].MaxT = -Inf, Tr[Now].MinF = Inf;
}void Modify(int &Now, int l, int r, int Side, int p, int t) {if (!Now) {Now = ++ tot;Clear(tot);}Tr[Now].MinF = min(Tr[Now].MinF, F[p]);Tr[Now].MaxT = max(Tr[Now].MaxT, t);if (l == r) return;int Mid = (l + r) >> 1;if (Side <= Mid) Modify(Tr[Now].l, l, Mid, Side, p, t); elseModify(Tr[Now].r, Mid + 1, r, Side, p, t);
}int QueryMinF(int Now, int l, int r, int lx, int rx) {if (rx < l || lx > r || !Now) return Inf;if (l >= lx && r <= rx) return Tr[Now].MinF;int Mid = (l + r) >> 1;return min(QueryMinF(Tr[Now].l, l, Mid, lx, rx), QueryMinF(Tr[Now].r, Mid + 1, r, lx, rx));
}int QueryMaxT(int Now, int l, int r, int lx, int rx) {if (rx < l || lx > r || !Now) return -Inf;if (l >= lx && r <= rx) return Tr[Now].MaxT;int Mid = (l + r) >> 1;return max(QueryMaxT(Tr[Now].l, l, Mid, lx, rx), QueryMaxT(Tr[Now].r, Mid + 1, r, lx, rx));
}void Solve(int l, int r) {if (l == r) return;int Mid = (l + r) >> 1;Solve(l, Mid);int num = 0;for (int i = l; i <= r; i ++) G[++ num] = Node(i, D[i].y, D[i].t);sort(G + 1, G + num + 1, CmpY);Root = tot = 1;Clear(Root);for (int i = 1; i <= num; i ++) {int x = G[i].x, y = G[i].y, t = G[i].t;if (x <= Mid) {if (F[x] + t <= Lim) Modify(Root, 0, Lim, F[x] + t, x, t);} else {int p1 = t - QueryMaxT(Root, 0, Lim, 0, t), p2 = QueryMinF(Root, 0, Lim, t, Lim);F[x] = min(F[x], min(p1, p2));}}Solve(Mid + 1, r);
}int main() {scanf("%d%d", &N, &T);Lim = T * 2 + 1;for (int i = 1; i <= N; i ++) {int t, s;scanf("%d%d", &t, &s);D[i] = Node(s + t, s - t, t);}D[++ N] = Node(T, -T, T);sort(D, D + N + 1, CmpX);memset(F, 60, sizeof F);for (int i = 0; i <= N; i ++) {if (D[i].x == T && D[i].y == -T && D[i].t == T) End = i;if (D[i].x == 0 && D[i].y == 0 && D[i].t == 0) F[i] = 0;}Solve(0, N);printf("%d\n", F[End]);
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
