SPOJ - LIS2 Another Longest Increasing Subsequence Problem

cdq分治,dp(i)表示以i为结尾的最长LIS,那么dp的递推是依赖于左边的。

因此在分治的时候需要利用左边的子问题来递推右边。

(345ms? 区间树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);//这是为了保证严格的单调性
}

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维度

        for(int i = l; i < r; i++){
            int k = id[i];
            if(k < md){ //position 维度
                add(ys[k],dp[k]); //BIT下标是 y维度
            }
            else {
                //查询位置前保证了BIT里的元素, 位置md之前,x严格小于待查元素
                dp[k] = max(dp[k], mx_pfx(ys[k]-1));//y严格小于待查元素的最大dp值
            }
        }

        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;
}
时间: 2024-08-09 18:34:02

SPOJ - LIS2 Another Longest Increasing Subsequence Problem的相关文章

SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=19929 Description Given a sequence of N pairs of integers, find the length of the longest incre

SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)

Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it. An increasing sequence A1..An is a sequence such that for every i < j, Ai < Aj. A subsequence of a sequence is a sequence that appears in the same

LintCode Longest Increasing Subsequence

Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return the length of the LIS. Clarification What's the definition of longest increasing subsequence? The longest increasing subsequence problem is to find a

LintCode刷题笔记--Longest Increasing Subsequence

动态规划 描述: Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return the length of the LIS. Clarification What's the definition of longest increasing subsequence? The longest increasing subsequence problem is t

[LintCode]76. Longest Increasing Subsequence

Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return the length of the LIS. Example For [5, 4, 1, 2, 3], the LIS is [1, 2, 3], return 3 For [4, 2, 4, 5, 3, 7], the LIS is [2, 4, 5, 7], return 4 Challenge

300. Longest Increasing Subsequence

Problem statement: Given an unsorted array of integers, find the length of longest increasing subsequence. For example,Given [10, 9, 2, 5, 3, 7, 101, 18],The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there

Dynamic Programming | Set 3 (Longest Increasing Subsequence)

在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 和 Dynamic Programming | Set 2 (Optimal Substructure Property) 中我们已经讨论了重叠子问题和最优子结构性质,现在我们来看一个可以使用动态规划来解决的问题:最长上升子序列(Longest Increasing Subsequence(LIS)). 最长上升子序列问题,致力于在一个给定的序列中找到一个最长的子序列

[Coding Made Simple] Longest Increasing Subsequence

Given an array, find the longest increasing subsequence in this array. The same problem link. [LintCode] Longest Increasing Subsequence

[Leetcode] Binary search--300. Longest Increasing Subsequence

Given an unsorted array of integers, find the length of longest increasing subsequence. For example,Given [10, 9, 2, 5, 3, 7, 101, 18],The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than o