zoukankan      html  css  js  c++  java
  • Hdu4742 (CDQ分治)

    题意:给出n个三维点对(x,y,z),可随意排列,求三维非严格最长上升子序列长度和最长上升子序列数量。

    输入格式:第一行为一整数T表示用例组数,每组用例第一行为一整数n表示点数,之后n行每行三个整数x,y,z表示一个点。

    输出格式:对于每组用例,输出两个整数分别表示三维非严格最长上升子序列长度和最长上升子序列数量。

    #include<cstdio>
    #include<algorithm>
    #define mid ((l + r) >> 1)
    #define mp(a, b) make_pair(a, b)
    #define    fi first
    #define se second
    using namespace std;
    const int N = 1e5 + 5;
    
    typedef pair<int, int> pii;
    
    int t, n, x, y, z, len;
    int kk[N];
    pii dp[N], c[N];
    
    struct Point{
        int x, y, z, id;
    }p[N], temp[N];
    
    bool cmp1(const Point &a, const Point &b) { return a.x < b.x; }
    
    bool cmp2(const Point &a, const Point &b) { return a.y < b.y; }
    
    inline int lowbit(int x) { return x & -x; }
    
    pii ask(int x){
        pii ans = mp(0, 0);
        while(x){
            if(c[x].fi > ans.fi)  ans = c[x];
            else if(c[x].fi == ans.fi)  ans.se += c[x].se;
            x -= lowbit(x);  
        }
        return ans;
    }
    
    void modify(int x, pii k){
        while(x <= len){
            if(c[x].fi < k.fi)  c[x] = k;
            else if(c[x].fi == k.fi)  c[x].se += k.se;
            x += lowbit(x);
        }
    }
    
    void clear(int x){
        while(x <= len){
            c[x] = mp(0, 0);
            x += lowbit(x);
        }
    }
    
    void CDQ(int l, int r){
        if(l == r)  return ;
        CDQ(l, mid);
        for(int i = l; i <= r; ++i)  temp[i] = p[i];
        sort(temp + l, temp + r + 1, cmp2);
        for(int i = l; i <= r; ++i){
            if(temp[i].id > mid){
                int id = temp[i].id;
                pii q = ask(temp[i].z);
                ++q.first; 
                if(dp[id].fi < q.fi)  dp[id] = q;
                else if(dp[id].fi == q.fi)  dp[id].se += q.se;
            }
            else    modify(temp[i].z, dp[temp[i].id]);
        }
        for(int i = l; i <= r; ++i)  if(temp[i].id <= mid) clear(temp[i].z);
        CDQ(mid + 1, r);  
    }
    
    int main(){
        scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i)     dp[i].fi = dp[i].se = 1;
            for(int i = 1; i <= n; ++i){
                scanf("%d%d%d", &x, &y, &z);
                p[i] = Point{x, y, z, i};
                kk[i] = z;
            }
            sort(p + 1, p + 1 + n, cmp1);
            sort(kk + 1, kk + 1 + n);
            len = unique(kk + 1, kk + 1 + n) - kk - 1;
            for(int i = 1; i <= n; ++i)  p[i].z = lower_bound(kk + 1, kk + 1 + len, p[i].z) - kk,  p[i].id = i;
            CDQ(1, n);
            pii ans = mp(0, 0);
            for(int i = 1; i <= n; ++i){
                if(dp[i].fi > ans.fi)   ans = dp[i];
                else if(dp[i].fi == ans.fi)  ans.se += dp[i].se;
            }
            printf("%d %d
    ", ans.fi, ans.se);
        }
        return 0;
    }
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    Redis 存储字符串和对象
    深入理解Java中的final关键字
    Redis缓存Object,List对象
    JVM最多能创建多少个线程: unable to create new native thread
    Java中如何使用Redis做缓存
    Fiddler抓包11-HTTPS证书Actions无法导出问题
    Fiddler抓包10-会话框添加查看get与post请求类型
    python接口自动化10-token登录
    python接口自动化9-https请求(SSL)
    python爬虫beautifulsoup4系列4-子节点
  • 原文地址:https://www.cnblogs.com/214txdy/p/14024400.html
Copyright © 2011-2022 走看看