Another LISTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 258 Accepted Submission (s): 45 Problem DescriptionThere is a sequence firstly empty. we begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. now, we want to know length of the LIS (Longest Increasing Subsequence) after every time's add. inputAn integer T (T <= 10), indicating there are T test cases.
For every test case, an integer N (1 <= n <= 100000) comes first, then there are n numbers, the k-th number XK means that we add number k at position XK (0 <= XK <= k-1 ). see hint for more details. outputfor the k-th test case, first output "case # K:" in a separate line, then followed n lines indicating the answer. output a blank line after every test case. idea: First, we leave all positions (1-N) Empty and record the set S. Obviously, the number of null positions in the Set S is N; Step 1: The only value that can be determined in the final state is the value n; its position is the value [N] + 1 (my position is from 1-N) in the Set S) then, the value of the position P is N, and the null position of the Set S is-1, it is located at the null position of value [n-1] + 1 in the s set, and then sat down. After sitting down in turn, there will be a value in each position; in this step, the line segment tree can be processed at the nlog (n) time. In the second step, the lis of the vertex is used. Obviously, DP [J]> = DP [I] (j> I ); remember that the first step is exactly the same as a PKU question!
# Include <iostream> # include <cmath> # include <algorithm> using namespace STD; const int n = 100002; struct seg {int L, R, totnum; int mid () {return (L + r)> 1 ;}}; seg [3 * n]; int POS [N], DIA [N], DP [N], ans [N]; void maketree (int l, int R, int c) {seg [C]. L = L; seg [C]. R = r; seg [C]. totnum = r-L + 1; if (L = r) return; int mid = seg [C]. mid (); maketree (L, mid, C <1); maketree (Mid + 1, R, (C <1) + 1 );} int finds (int c, int num) {If (SEG [C]. L = seg [C]. r) return seg [C]. l; If (SEG [C <1]. totnum <num) return finds (C <1) + 1, num-seg [C <1]. totnum); elsereturn finds (C <1, num);} void del (int c, int p) {seg [C]. totnum --; If (SEG [C]. L = seg [C]. r) return; int mid = seg [C]. mid (); If (P <= mid) del (C <1, P); elsedel (C <1) + 1, P);} int main () {int I, j, N, T, Cas, P; scanf ("% d", & T); For (CAS = 1; CAS <= T; CAS ++) {scanf ("% d", & N); for (I = 1; I <= N; I ++) scanf ("% d ", & Dia [I]); maketree (1, n, 1); for (I = N; I> = 1; I --) {P = finds (1, dia [I] + 1); POS [p] = I; del (1, P);} DP [0] = 0; int h = 0, L = 0, mid, temp, Len = 0; printf ("case # % d:/N", CAS); for (I = 1; I <= N; I ++) {temp = POS [I]; L = 0, H = Len; while (L <= h) {mid = (L + H)> 1; if (temp> DP [Mid]) L = Mid + 1; elseh = mid-1;} DP [l] = temp; ans [temp] = L; if (L> Len) Len ++;} ans [0] = 0; for (I = 1; I <= N; I ++) {If (ANS [I] <ans [I-1]) ans [I] = ans [I-1]; printf ("% d/N", ANS [I]);} printf ("/N");} return 0 ;}