二维LIS
Posted stddddd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维LIS相关的知识,希望对你有一定的参考价值。
其实这题太水了
就是很简单的线段树维护cdq。
前对后影响用线段树维护一下即可。
具体看代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 20004 5 using namespace std; 6 int n,dp[N],ans; 7 struct node 8 { 9 int xi; 10 int yi; 11 int no; 12 bool friend operator < (node x,node y) 13 { 14 return x.xi<y.xi; 15 } 16 }a[N],tmp[N]; 17 struct segtree 18 { 19 int vl[N<<2]; 20 void update(int to,int aim,int lx,int rx,int nx) 21 { 22 if(lx==rx) 23 { 24 vl[nx]=max(vl[nx],aim); 25 return; 26 } 27 int mid=(lx+rx)>>1; 28 if(to<=mid) 29 { 30 update(to,aim,lx,mid,nx<<1); 31 }else 32 { 33 update(to,aim,mid+1,rx,(nx<<1)|1); 34 } 35 vl[nx]=max(vl[nx<<1],vl[(nx<<1)|1]); 36 } 37 int query(int ln,int rn,int lx,int rx,int nx) 38 { 39 if(ln<=lx&&rn>=rx) 40 { 41 return vl[nx]; 42 } 43 int mid=(lx+rx)>>1; 44 int ret=0; 45 if(ln<=mid) 46 { 47 ret=max(ret,query(ln,rn,lx,mid,nx<<1)); 48 } 49 if(rn>mid) 50 { 51 ret=max(ret,query(ln,rn,mid+1,rx,(nx<<1)|1)); 52 } 53 return ret; 54 } 55 }tr; 56 void merge(int lx,int rx) 57 { 58 int mid=(lx+rx)>>1; 59 for(int i=lx;i<=rx;i++) 60 { 61 tmp[i]=a[i]; 62 } 63 for(int i=lx,j=mid+1,k=lx;k<=rx;k++) 64 { 65 if(i<=mid&&j<=rx) 66 { 67 a[k]=tmp[i]<tmp[j]?tmp[i++]:tmp[j++]; 68 }else 69 { 70 a[k]=i<=mid?tmp[i++]:tmp[j++]; 71 } 72 } 73 } 74 void sol(int lx,int rx) 75 { 76 if(lx==rx) 77 { 78 return; 79 } 80 int mid=(lx+rx)>>1; 81 for(int i=lx;i<=rx;i++) 82 { 83 tmp[i]=a[i]; 84 } 85 for(int i=lx,j=mid+1,k=lx;k<=rx;k++) 86 { 87 if(tmp[k].no<=mid) 88 { 89 a[i++]=tmp[k]; 90 }else 91 { 92 a[j++]=tmp[k]; 93 } 94 } 95 sol(lx,mid); 96 memset(tr.vl,0,sizeof(tr.vl)); 97 for(int i=mid+1,j=lx;i<=rx;i++) 98 { 99 while(a[j].xi<a[i].xi) 100 { 101 if(j>mid) 102 { 103 break; 104 } 105 tr.update(a[j].yi,dp[a[j].no],1,N,1); 106 j++; 107 } 108 if(a[i].yi!=1) 109 { 110 dp[a[i].no]=max(dp[a[i].no],tr.query(1,a[i].yi-1,1,N,1)+1); 111 }else 112 { 113 dp[a[i].no]=max(dp[a[i].no],1); 114 } 115 } 116 sol(mid+1,rx); 117 merge(lx,rx); 118 } 119 int main() 120 { 121 scanf("%d",&n); 122 for(int i=1;i<=n;i++) 123 { 124 scanf("%d%d",&a[i].xi,&a[i].yi); 125 a[i].no=i; 126 } 127 sort(a+1,a+1+n); 128 dp[1]=1; 129 sol(1,n); 130 for(int i=1;i<=n;i++) 131 { 132 ans=max(ans,dp[i]); 133 } 134 printf("%d ",ans); 135 return 0; 136 }
以上是关于二维LIS的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1069 Monkey and Banana(二维偏序LIS的应用)
HDU 1025 Constructing Roads In JGShining's Kingdom(二维LIS)
leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段