##题面
Description
给定N个数对(xi, yi),求最长上升子序列的长度。上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj。

Input
Output
Sample Input
8

1 3

3 2

1 1

4 5

6 3

9 9

8 7

7 6
Sample Output
3
HINT

数据范围100000

##解题思路
  CDQ分治。其实跟模板题的思路差不多,就是用树状数组维护$dp$最大值。注意一下更新的顺序,就是要从左边往右边更新,所以应该先向左分治,再处理,再向右分治。

##代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std;
const int MAXN = 100005; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
} int n,dp[MAXN],f[MAXN],cpy[MAXN],u,ans;
struct Data{
int id,x,y;
friend bool operator<(const Data A,const Data B){
return A.x<B.x;
}
}data[MAXN],tmp[MAXN]; inline void add(int x,int k){
for(;x<=u;x+=x&-x) f[x]=max(f[x],k);
} inline int query(int x){
int ret=0;
for(;x;x-=x&-x) ret=max(ret,f[x]);
return ret;
} inline void clear(int x){
for(;x<=u;x+=x&-x) f[x]=-1;
} inline bool cmp(Data A,Data B){
return A.id<B.id;
} void cdq(int l,int r){
if(l==r) return ;int mid=(l+r)>>1;cdq(l,mid);
int L=l,R=mid+1,o=l;
sort(data+mid+1,data+r+1);
while(L<=mid && R<=r){
if(data[L].x<data[R].x) add(data[L].y,dp[data[L].id]),L++;
else dp[data[R].id]=max(dp[data[R].id],query(data[R].y-1)+1),R++;
}
while(R<=r) {dp[data[R].id]=max(dp[data[R].id],query(data[R].y-1)+1);R++;}
for(int i=l;i<=mid;i++) clear(data[i].y);sort(data+mid+1,data+r+1,cmp);
cdq(mid+1,r);L=l;R=mid+1;
while(L<=mid && R<=r) {
if(data[L].x<data[R].x) tmp[o++]=data[L++];
else tmp[o++]=data[R++];
}
while(L<=mid) tmp[o++]=data[L++];
while(R<=r) tmp[o++]=data[R++];
for(int i=l;i<=r;i++) data[i]=tmp[i];
} int main(){
memset(f,-1,sizeof(f));n=rd();
for(int i=1;i<=n;i++) data[i].x=rd(),data[i].y=cpy[i]=rd(),data[i].id=i,dp[i]=1;
sort(cpy+1,cpy+1+n);u=unique(cpy+1,cpy+1+n)-cpy-1;
for(int i=1;i<=n;i++) data[i].y=lower_bound(cpy+1,cpy+1+u,data[i].y)-cpy;cdq(1,n);
for(int i=1;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
return 0;
}

BZOJ 2225: [Spoj 2371]Another Longest Increasing (CDQ分治+dp)的更多相关文章

  1. BZOJ 2225 [Spoj 2371]Another Longest Increasing(CDQ分治)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2225 [题目大意] 给定N个数对(xi,yi),求最长上升子序列的长度. 上升序列定义 ...

  2. bzoj 2225 [Spoj 2371]Another Longest Increasing

    这道题 连续上升的三元组 且已经按照第一维排好序了. 直接上CDQ分治即可 当然也是可以2-Dtree解决这个 问题 但是感觉nlog^2 比nsqrt(n)要快一些.. 算是复习一发CDQ分治吧 也 ...

  3. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

  4. BZOJ2225: [Spoj 2371]Another Longest Increasing CDQ分治,3维LIS

    Code: #include <cstdio> #include <algorithm> #include <cstring> #define maxn 20000 ...

  5. BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组

    BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组 Description        给定N个数对(xi, yi),求最长上升子 ...

  6. SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

    Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...

  7. SPOJ LIS2 - Another Longest Increasing Subsequence Problem(CDQ分治优化DP)

    题目链接  LIS2 经典的三维偏序问题. 考虑$cdq$分治. 不过这题的顺序应该是 $cdq(l, mid)$ $solve(l, r)$ $cdq(mid+1, r)$ 因为有个$DP$. #i ...

  8. SPOJ - LIS2 Another Longest Increasing Subsequence Problem

    cdq分治,dp(i)表示以i为结尾的最长LIS,那么dp的递推是依赖于左边的. 因此在分治的时候需要利用左边的子问题来递推右边. (345ms? 区间树TLE /****************** ...

  9. HPU第三次积分赛-D:Longest Increasing Subsequence(DP)

    Longest Increasing Subsequence 描述 给出一组长度为n的序列,a1​,a2​,a3​,a4​...an​, 求出这个序列长度为k的严格递增子序列的个数 输入 第一行输入T ...

随机推荐

  1. Mybatis调用Oracle中的存储过程和function

    一.Mybatis调用存储过程 1 在数据库中创建以下的存储过程create or replace procedure pro_hello(p_user_name in varchar2,p_resu ...

  2. RAM SSO功能重磅发布 —— 满足客户使用企业本地账号登录阿里云

    阿里云RAM (Resource Access Management)为客户提供身份与访问控制管理服务.使用RAM,可以轻松创建并管理您的用户(比如雇员.企业开发的应用程序),并控制用户对云资源的访问 ...

  3. 逆向思维——cf1241D

    /* 给定一个序列a,每次可以把值为x的所有元素放到a的首部或尾部,问将a变为lis的最少操作步数 对原序列离散化后重新打标记, 可以反着来考虑这个问题:即固定连续的元素值为[l,r]的点不动,那么剩 ...

  4. 经典sql题练习50题

    -- 1.查询"01"课程比"02"课程成绩高的学生的信息及课程分数 select a.* ,b.s_score as 01_score,c.s_score a ...

  5. __iomem作用

    最近在看网卡驱动时查看ioremap函数发现调用最低层用__iomem修饰了ioremap的第一个参数(unsigned int)ioremap(S3C24XX_PA_CS8900, SZ_1M) + ...

  6. idea无法引用jar包中的class

    最近由eclipse换idea的过程中,出现了一个很奇妙的问题! 项目是maven+git+idea管理的,idea某次在使用的过程中,电脑死机重启后,发现无法引用jar包中的class.包括jdk中 ...

  7. (转) C#中使用throw和throw ex抛出异常的区别

    通常,我们使用try/catch/finally语句块来捕获异常,就像在这里说的.在抛出异常的时候,使用throw和throw ex有什么区别呢? 假设,按如下的方式调用几个方法: →在Main方法中 ...

  8. Servlet源码分析

    Servlet API的核心就是javax.servlet.Servlet接口,所有的Servlet 类(抽象的或者自己写的)都必须实现这个接口.在Servlet接口中定义了5个方法,其中有3个方法是 ...

  9. new delete

    malloc/free是标准的库函数,而new/delete是操作符 匹配使用原则:malloc(calloc/realloc)和free 以及new/new[] 和delete/delete[]; ...

  10. UVA 356 - Square Pegs And Round Holes

    题目:在一个2n*2n的网格中间画一个直径为2n-1的圆,问圆内部的格子以及和圆相交的格子个数. 思路:只要考虑1 / 4圆的点就行,用点到原点距离与半径比较,当格子左下方和右上方都在格子里时,格子在 ...