• SPOJ


    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
    ",*max_element(dp,dp+N));
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        solve();
        return 0;
    }
  • 相关阅读:
    跟小静学CLR via C#(12)委托Delegate
    跟小静读CLR via C#(02)基元类型、引用类型、值类型
    跟小静读CLR via C#(07)静态类,分部类
    jQuery折叠菜单
    ajax调用后台Datatable
    跟小静读CLR via C#(11)无参属性、索引器
    跟小静读CLR via C#(08)操作符
    跟小静读CLR via C#(05) 访问限定、数据成员
    AjaxPro排错指南
    跟小静读CLR via C#(14)可空值类型,关于?和??的故事
  • 原文地址:https://www.cnblogs.com/jerryRey/p/5011307.html
Copyright © 2020-2023  润新知