We can open a one-dimensional array w []. The subscript of the array is the endpoint value of the range. cow is at the beginning of w [s. When we encounter an interval, we can see how many values will be covered in this interval (actually the number of steps taken to the endpoint of the previous interval) and enumerate these values to update the two endpoint values of the current interval, after enumeration, the overwritten values are deleted and the two new endpoint values are added. values outside the range are not considered. In the end, the distance between these endpoint values and the origin point is the answer. Of course, the minimum value should be selected from these values.
This involves deleting the range overwrite value and adding the value of the two vertices. If arrays are used, the worst case is O (n) each time, and each traversal of the linked list is a waste of time.
Here we select the line segment tree. The line segment tree is deleted and added as logn. the number of times each deleted depends on the remaining endpoint. Each endpoint is added and deleted once at most, so the complexity is 2 * N * logL, L is the maximum distance in the interval.
PS: It's a miserable drama. It's over ms and the code is short.
Line Segment tree, over ms, and nearly doubled the amount of code
........
First look at the linked list Code:
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <utility>
# Include <iostream>
# Include <list>
Using namespace std;
# Define MP make_pair
# Define x first
# Define y second
Const int INF = 0x3f3f3f;
Const int maxn = 100010;
Typedef pair <int, int> pii;
List <pii> p;
List <pii>: iterator it;
Int w [maxn] [2];
Inline int f (int v)
{
Return v> = 0? V:-v;
}
Int main ()
{
Int n, s;
Int l, r;
Scanf ("% d", & n, & s );
For (int I = 0; I <n; I ++) scanf ("% d", & w [I] [0], & w [I] [1]);
P. push_back (MP (0, s ));
For (int I = n-1; I> = 0; I --){
L = w [I] [0], r = w [I] [1];
Int ll = INF, rr = INF;
For (it = p. begin (); it! = P. end ();){
If (l <= it-> y & it-> y <= r ){
Ll = min (ll, it-> x + f (it-> y-l ));
Rr = min (rr, it-> x + f (it-> y-r ));
It = p. erase (it );
} Else if (it-> y> r)
Break;
Else it ++;
}
If (ll <INF ){
P. insert (it, MP (ll, l ));
P. insert (it, MP (rr, r ));
}
}
Int ans = INF;
For (it = p. begin (); it! = P. end (); it ++ ){
Ans = min (ans, it-> x + f (it-> y ));
}
Printf ("% d \ n", ans );
}
Then the line segment Tree Code:
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <utility>
# Include <iostream>
Using namespace std;
# Define lson l, m, rt <1
# Define rson m + 1, r, rt <1 | 1
Const int INF = 0x3f3f3f;
Const int maxn = 200010;
Typedef pair <int, int> pii;
Int cover [maxn <2], MinV [maxn <2], P [maxn <2];
Int w [maxn] [2];
Void PushUp (int rt)
{
MinV [rt] = MinV [rt <1];
P [rt] = P [rt <1];
If (MinV [rt]> MinV [rt <1 | 1]) {
MinV [rt] = MinV [rt <1 | 1];
P [rt] = P [rt <1 | 1];
}
}
Void update (int p, int c, int l, int r, int rt)
{
If (l = r ){
MinV [rt] = c;
P [rt] = l;
Return;
}
Int m = (l + r)> 1;
If (p <= m) update (p, c, lson );
Else update (p, c, rson );
PushUp (rt );
}
Pii query (int L, int R, int l, int r, int rt)
{
If (L <= l & r <= R) return pii (MinV [rt], P [rt]);
Int m = (l + r)> 1;
Pii u (INF, 0), v;
If (L <= m ){
V = query (L, R, lson );
If (u. first> v. first) u = v;
}
If (m <R ){
V = query (L, R, rson );
If (u. first> v. first) u = v;
}
PushUp (rt );
Return u;
}
Inline int f (int x)
{
Return x> = 0? X:-x;
}
Int main ()
{
Int n, s;
Int L = INF, R =-INF;
Int l, r;
Memset (MinV, 0x3f, sizeof (MinV ));
Scanf ("% d", & n, & s );
For (int I = 0; I <n; I ++ ){
Scanf ("% d", & w [I] [0], & w [I] [1]);
L = min (L, w [I] [0]);
R = max (R, w [I] [1]);
}
Update (w [n-1] [0], f (s-w [n-1] [0]), L, R, 1 );
Update (w [n-1] [1], f (s-w [n-1] [1]), L, R, 1 );
For (int I = n-2; I> = 0; I --){
L = w [I] [0], r = w [I] [1];
Int ll = INF, rr = INF;
While (true ){
Pii u = query (l, r, L, R, 1 );
If (u. first = INF) break;
Ll = min (ll, u. first + f (u. second-l ));
Rr = min (rr, u. first + f (u. second-r ));
Update (u. second, INF, L, R, 1 );
}
Update (l, ll, L, R, 1 );
Update (r, rr, L, R, 1 );
}
Int ans = INF;
For (int I = L; I <= R; I ++ ){
Pii u = query (I, I, L, R, 1 );
Ans = min (ans, u. first + f (u. second ));
}
Printf ("% d \ n", ans );
}