• 二维LIS(CDQ分治)


    题目描述

    给定一个长度为N的序列S,S的每个元素pi是一个二元组(xi,yi),定义pi<pj当且仅当xi<xj并且yi<yj,求S的最长上升子序列长度

    输入格式

    第一行一个N,表示一共有N个元素

    接下来有N行,每行包含两个正整数xi,yi

    输出格式

    输出一行一个整数,代表序列S的最长上升子序列的长度

    一道很好的模板题,比较入门吧

    CDQ分治+线段树/树状数组维护最大值就好了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct nasm{
     6     int x,y,z;
     7 }a[100000];
     8 int f[1000000];
     9 int tr[1000000];
    10 int tmp[100000];
    11 int n;
    12 bool cmp(nasm g,nasm u)
    13 {
    14     return g.y<u.y;
    15 }
    16 bool cmq(nasm g,nasm u)
    17 {
    18     return g.x<u.x;
    19 }
    20 void updt(int pi,int v,int l,int r,int spc)
    21 {
    22     if(l==r)
    23     {
    24         tr[spc]=v==0?v:max(v,tr[spc]);
    25         return ;
    26     }
    27     int m=(l+r)>>1;
    28     if(pi<=m)
    29         updt(pi,v,l,m,spc<<1);
    30     else    
    31         updt(pi,v,m+1,r,spc<<1|1);
    32     tr[spc]=max(tr[spc<<1],tr[spc<<1|1]);
    33 }
    34 int ask(int ll,int rr,int l,int r,int spc)
    35 {
    36     if(ll>rr)return 0;
    37     if(l>=ll&&r<=rr)return tr[spc];
    38     int m=(l+r)>>1;
    39     if(m>=rr)return ask(ll,rr,l,m,spc<<1);
    40     if(m<ll)return ask(ll,rr,m+1,r,spc<<1|1);
    41     return max(ask(ll,rr,l,m,spc<<1),ask(ll,rr,m+1,r,spc<<1|1));
    42 }
    43 void wrk(int l,int r)
    44 {
    45     int mid=(l+r)>>1;
    46     sort(a+l,a+mid+1,cmp);
    47     sort(a+mid+1,a+r+1,cmp);
    48     for(int i=l,j=mid+1;j<=r;j++)
    49     {
    50         for(;a[i].y<a[j].y&&i<=mid;i++)
    51             updt(a[i].z,f[a[i].x],1,n,1);
    52         f[a[j].x]=max(f[a[j].x],ask(1,a[j].z-1,1,n,1)+1);
    53     }
    54     for(int i=l;i<=mid;i++)updt(a[i].z,0,1,n,1);
    55     sort(a+mid+1,a+r+1,cmq);
    56 }
    57 void cdq(int l,int r)
    58 {
    59     if(l==r)
    60         return ;
    61     int mid=(l+r)>>1;
    62     cdq(l,mid);
    63     wrk(l,r);
    64     cdq(mid+1,r);
    65     
    66 }
    67 int erf(int l,int r,int aim)
    68 {
    69     if(l==r)return l;
    70     int m=(l+r)>>1;
    71     if(aim<=tmp[m])
    72         return erf(l,m,aim);
    73     return erf(m+1,r,aim);
    74 }
    75 int main()
    76 {
    77     scanf("%d",&n);
    78     for(int i=1;i<=n;i++)
    79     {
    80         scanf("%d%d",&a[i].y,&a[i].z);
    81         f[i]=1;
    82         a[i].x=i;
    83         tmp[i]=a[i].z;
    84     }
    85     sort(tmp+1,tmp+n+1);
    86     for(int i=1;i<=n;i++)
    87         a[i].z=erf(1,n,a[i].z);
    88     cdq(1,n);
    89     int ans=0;
    90     for(int i=1;i<=n;i++)
    91         ans=max(ans,f[i]);
    92     printf("%d
    ",ans);
    93     return 0;
    94 }
    二维LIS
  • 相关阅读:
    linux下设置SSH无密码登陆
    设置sudo权限
    集群重启后启动ambari-server访问Web页面无法启动集群解决
    使用Ambari部署hadoop集群
    centos7.6安装python3.7
    Locust
    测试框架(自然语言)
    Maven之(七)pom.xml配置文件详解
    git的使用
    elastic search(es)安装
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9404518.html
Copyright © 2020-2023  润新知