二维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\n",ans);
135     return 0;
136 }

原文地址:https://www.cnblogs.com/stddddd/p/9995861.html

时间: 2024-10-15 22:15:57

二维LIS的相关文章

HDU 1025 Constructing Roads In JGShining&#39;s Kingdom(二维LIS)

Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23467    Accepted Submission(s): 6710 Problem Description JGShining's kingdom consists of 2n(n is no mo

二维LIS(CDQ分治)

题目描述 给定一个长度为N的序列S,S的每个元素pi是一个二元组(xi,yi),定义pi<pj当且仅当xi<xj并且yi<yj,求S的最长上升子序列长度 输入格式 第一行一个N,表示一共有N个元素 接下来有N行,每行包含两个正整数xi,yi 输出格式 输出一行一个整数,代表序列S的最长上升子序列的长度 一道很好的模板题 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 usin

acd - 1216 - Beautiful People(二维LIS)

题意:一个人有两个属性S, B(1 ≤ Si, Bi ≤ 10^9),当两个人的这两个属性满足 S1 < S2 && B1 < B2 或者 S1 > S2 && B1 > B2 时,这两个人不会讨厌对方.现给出 N 个人(2 ≤ N ≤ 100 000)的属性,求最多能有多少个人,他们之间任意两人都不会讨厌对方. 题目链接:http://acdream.info/problem?pid=1216 -->>容易想到是一个二维的LIS模型..

UVA10285 二维 LIS

题意: 求二维数组最长不下降子序列 解题: 记忆化搜索, d[i][j]为以 (i, j) 为终点的最长不下降序列的长度,然后四个方向 dfs ~ #include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 110; const int INF = 0x3f3f3f3f; char nm[maxn]; int a[maxn][maxn], d[maxn][maxn]; int gx[4]

SGU 199. Beautiful People 二维LIS

第一维排序 第二维LIS #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int dp[100010]; int p[100010]; struct node { int x, y, id; }a[100010]; bool cmp(node a, node b) { if(a.x != b.x) return a.x < b.x; return a.y

ACdream 1216——Beautiful People——————【二维LIS,nlogn处理】

Beautiful People Special Judge Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description The most prestigious sports club in one city has exactly N members. Each of its members

二维无序LIS ACdream1216 Beautiful People

传送门:点击打开链接 题意:告诉你n个人,每个人有个s和b连个值,要求从n个人中选出数量最多的人,使任意两个人(i,j)都有si<sj且bi<bj或者sj<si且bj<bi,要求输出选出数量最多的人,且输出是哪一些人,其中题目是spj. 思路:首先很容易想到DAG模型,但是这题的n<=100000,所以用DAG模型复杂度太高了.然后会想到LIS,可能就会想到用二维线段树去做. 其实仔细想想这道题,和普通的LIS还是有不一样的地方的.那就是他的顺序并不是给定的!!什么意思呢,虽

hdu----(1677)Nested Dolls(DP/LIS(二维))

Nested Dolls Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2704    Accepted Submission(s): 802 Problem Description Dilworth is the world’s most prominent collector of Russian nested dolls: he

【二维树状数组】See you~

https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A x y n1 :给格点(x,y)的值加n1 D x y n1: 给格点(x,y)的值减n1,如果现在格点的值不够n1,把格点置0 M x1 y1 x2 y2:(x1,y1)移动给(x2,y2)n1个 S x1 y1 x2 y2 查询子矩阵的和 [思路] 当然是二维树状数组 但是一定要注意:lowbi