Description
Xuejie needs to bring exactly m yuan for every shopping trip, but today she forgot to bring her wallet.
The poor doc had to make money for xuejie, but he had only one dollar in his pocket.
Fortunately, N of the doc's friends are particularly rich, and they promised to exchange some information with the doc.
The first friend said:
If the doc has no less than Ri yuan,
Doc can give all his money to this friend,
And exchange the VI yuan from this friend,
However, this exchange will waste TI's time.
Doc hopes to change to m yuan in the shortest time (in fact, it can be larger than m, because Doc can save private money), otherwise xuejie will be angry!
Format input format
Given t in the first line of input data, it indicates the total number of queries.
For each query, the first line gives two integers n and M.
Next n rows, each row is given three integers VI, RI and Ti. (ensure RI <= VI ).
Output Format
For each query, first output the query number. See the sample output.
The minimum time required for output. If the target cannot be completed,-1 is output.
Train of Thought: This question has been naked for a morning, and the idea is clear,... It is a waste of writing. It is a bit like overwriting a valuable line segment. Sort the right endpoint of the line segment. After discretization, query the minimum value between the left and right endpoints of each line segment, update the minimum value at the right endpoint, and finally, find the minimum value from M to the rightmost. This process uses the line segment tree, but it is very difficult to write. We still need to study it well...
(In the first place, the left and right endpoints are separated in Discrete mode, and the result is naked. Only the right endpoint is separated, and then lower_bound is used... Which of the following gods knows why ?!!!)
Code:
# Include <iostream>
# Include <cstdio>
# Include <queue>
# Include <algorithm>
Using namespace STD;
Struct use {
Int Li, RI, Ti;
} A [500000];
Int C [500000] = {0 };
Long long tree [800001] = {0}, maxn = 0x7ffffffffffffff;
Int my_comp (const use & X, const use & Y)
{
If (X. RI <Y. RI) return 1;
Return 0;
}
Void build (int I, int L, int R)
{
Int mid;
If (L! = 1) tree [I] = maxn;
Else tree [I] = 0;
If (L! = R)
{
Mid = (L + r)/2;
Build (I * 2, L, mid );
Build (I * 2 + 1, Mid + 1, R );
}
}
Long long work (int I, int L, int R, int LL, int RR)
{
Int mid;
Long long Minn;
If (LL <= L & R <= RR)
Return tree [I];
Mid = (L + r)/2;
Minn = maxn;
If (LL <= mid)
Minn = min (Minn, work (I * 2, L, mid, ll, RR ));
If (RR> mid)
Minn = min (Minn, work (I * 2 + 1, Mid + 1, R, ll, RR ));
Return Minn;
}
Void insert (int I, int L, int R, int LL, long K)
{
Int mid;
If (L = r)
{
Tree [I] = K;
Return;
}
Mid = (L + r)/2;
If (LL <= mid)
Insert (I * 2, L, mid, ll, k );
If (LL> mid)
Insert (I * 2 + 1, Mid + 1, R, ll, k );
Tree [I] = min (tree [I * 2], tree [I * 2 + 1]);
}
Int main ()
{
Int CI, T, I, J, n, m, size;
Long long ans, Minn;
Scanf ("% d", & T );
For (CI = 1; CI <= T; ++ CI)
{
Scanf ("% d", & N, & M );
For (I = 1; I <= N; ++ I)
Scanf ("% d", & A [I]. Ri, & A [I]. Li, & A [I]. Ti );
Sort (a + 1, A + n + 1, my_comp );
C [1] = 1;
For (I = 1; I <= N; ++ I)
C [I + 1] = A [I]. Ri;
Size = unique (C + 1, C + n + 2)-C-1;
Build (1, 1, size );
For (I = 1; I <= N; ++ I)
If (A [I]. RI> A [I]. li)
{
A [I]. Ri = lower_bound (C + 1, C + size + 1, a [I]. RI)-C;
Minn = work (1, 1, size, lower_bound (C + 1, C + size + 1, a [I]. li)-C, a [I]. RI );
If (Minn! = Maxn) insert (1, 1, size, a [I]. Ri, Minn + A [I]. Ti );
Else break;
}
Printf ("case # % d:", CI );
Ans = work (1, 1, size, lower_bound (C + 1, C + size + 1, m)-C, size );
If (ANS! = Maxn)
Printf ("% LLD \ n", ANS );
Else printf ("-1 \ n ");
}
}
Vijos1901 xuejie's wallet