CDQ Division, DP (i) indicates the longest lis ending with I, then DP recursion is dependent on the left.
So when you divide, you need to use the sub-question on the left to push the right side.
(345ms?) Interval Tree tle
/ ************************************************* ********
* ------------------ *
* author AbyssFish *
********************************************** ******** /
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <cmath>
#include <numeric>
using namespace std;
const int MAX_N = 100000 + 5;
int dp [MAX_N];
int x [MAX_N], y [MAX_N];
int ys [MAX_N];
int id [MAX_N];
int N;
int ns;
int * cur;
bool cmp (int a, int b)
{
return cur [a] <cur [b] || (cur [a] == cur [b] && a> b); // This is to ensure strict monotonicity
}
int compress (int * r, int * dat, int * a, int n)
{
for (int i = 0; i <n; i ++) {
r [i] = i;
}
cur = dat;
sort (r, r + n, cmp);
a [r [0]] = 1;
for (int i = 1; i <n; i ++) {
int k = r [i], p = r [i-1];
a [k] = dat [k] == dat [p]? a [p]: a [p] +1;
}
return a [r [n-1]];
}
int C [MAX_N];
void add (int yi, int d)
{
while (yi <= ns) {
C [yi] = max (C [yi], d);
yi + = yi & -yi;
}
}
int mx_pfx (int yi)
{
int re = 0;
while (yi> 0) {
re = max (C [yi], re);
yi & = yi-1;
}
return re;
}
void clr (int yi)
{
while (yi <= ns) {
C [yi] = 0;
yi + = yi & -yi;
}
}
void dv (int l, int r)
{
if (r-l <= 1) {
dp [l] ++;
}
else {
int md = (l + r) >> 1;
dv (l, md);
for (int i = l; i <r; i ++) id [i] = i;
sort (id + l, id + r, cmp); // x dimension
for (int i = l; i <r; i ++) {
int k = id [i];
if (k <md) {// position dimension
add (ys [k], dp [k]); // BIT subscript is y dimension
}
else {
// Ensure the elements in BIT before querying the position. Before the position md, x is strictly smaller than the element to be checked
dp [k] = max (dp [k], mx_pfx (ys [k] -1)); // y is strictly smaller than the maximum dp value of the element to be checked
}
}
for (int i = l; i <r; i ++) {
if (id [i] <md)
clr (ys [id [i]]);
}
dv (md, r);
}
}
void solve ()
{
scanf ("% d", & N);
for (int i = 0; i <N; i ++) {
scanf ("% d% d", x + i, y + i);
}
ns = compress (id, y, ys, N);
cur = x;
dv (0, N);
printf ("% d \ n", * max_element (dp, dp + N));
}
// # define LOCAL
int main ()
{
#ifdef LOCAL
freopen ("in.txt", "r", stdin);
#endif
solve ();
return 0;
}
Spoj-lis2 another longest increasing subsequence problem