SPOJ Another Longest Increasing Subsequence Problem

传送门:https://www.spoj.com/problems/LIS2/en/

题意:

给定 N个数对 \((x_i,y_i)\),求最长上升子序列的长度。上升序列定义为满足\((x_i,y_i)\)对i<j 有 \(x_i<x_j\) 且 \(y_i<y_j\)

题解:

一个三维最长链问题

第一维是存位置,第二维存x,第三维存y

注意查询是查询到p[i].z-1然后更新

细节方面和HDU4742是一样的

详情:https://www.cnblogs.com/buerdepepeqi/p/11193426.html

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
struct node {
int x, y, z;
} p[maxn];
bool cmpx(node A, node B) {
return A.x < B.x;
}
bool cmpy(node A, node B) {
return A.y < B.y;
}
int lowbit(int x) {
return x & (-x);
}
int n;
int dp[maxn];
int Hash[maxn];
int bit[maxn];
void add(int pos, int val) {
while(pos < n + 2) {
bit[pos] = max(bit[pos], val);
pos += lowbit(pos);
}
}
int sum(int pos) {
int res = 0;
while(pos) {
res = max(res, bit[pos]);
pos -= lowbit(pos);
}
return res;
}
void init(int x) {
for(int i = x; i < n + 2; i += lowbit(i))
bit[i] = 0;
}
void solve(int l, int r) { int mid = (l + r) >> 1;
sort(p + l, p + mid + 1, cmpy);
sort(p + mid + 1, p + r + 1, cmpy);
int j = l;
for(int i = mid + 1; i <= r; i++) {
while(j <= mid && p[j].y < p[i].y) {
add(p[j].z, dp[p[j].x]);
j++;
}
int tmp = sum(p[i].z - 1) + 1;
dp[p[i].x] = max(dp[p[i].x], tmp);
}
for(int i = l; i <= mid; i++) init(p[i].z);
sort(p + mid + 1, p + r + 1, cmpx);
}
void CDQ(int l, int r) {
if(l == r) {
return;
}
int mid = (l + r) >> 1;
CDQ(l, mid);
solve(l, r);
CDQ(mid + 1, r);
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].y, &p[i].z);
p[i].x = i;
dp[i] = 1;
Hash[i] = p[i].z;
} sort(Hash + 1, Hash + n + 1);
int cnt = unique(Hash + 1, Hash + n + 1) - Hash - 1;
for(int i = 1; i <= n; i++) {
p[i].z = lower_bound(Hash + 1, Hash + cnt + 1, p[i].z) - Hash;
}
// debug1(n);
CDQ(1, n);
int ans = 0;
for(int i = 1; i <= n; i++) {
ans = max(ans, dp[i]);
}
printf("%d\n", ans); return 0;
}

SPOJ Another Longest Increasing Subsequence Problem 三维最长链的更多相关文章

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

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

  2. SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)

    Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it ...

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

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

  4. SPOJ - LIS2 Another Longest Increasing Subsequence Problem

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

  5. [BZOJ2225][SPOJ2371]LIS2 - Another Longest Increasing Subsequence Problem:CDQ分治+树状数组+DP

    分析 这回试了一下三级标题,不知道效果怎么样? 回到正题,二维最长上升子序列......嗯,我会树套树. 考虑\(CDQ\)分治,算法流程: 先递归进入左子区间. 将左,右子区间按\(x\)排序. 归 ...

  6. [LintCode] Longest Increasing Subsequence 最长递增子序列

    Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...

  7. 【Lintcode】076.Longest Increasing Subsequence

    题目: Given a sequence of integers, find the longest increasing subsequence (LIS). You code should ret ...

  8. LintCode刷题笔记--Longest Increasing Subsequence

    标签: 动态规划 描述: Given a sequence of integers, find the longest increasing subsequence (LIS). You code s ...

  9. [LeetCode] Longest Increasing Subsequence

    Longest Increasing Subsequence Given an unsorted array of integers, find the length of longest incre ...

随机推荐

  1. 数组map用法总结

    数组中,map方法,指的是是数组的映射. map基本语法如下:function回调支持3个参数,第1个是遍历的数组内容:第2个是对应的数组索引,第3个是数组本身. map方法的作用不难理解,“映射”嘛 ...

  2. hdu 2844 混合背包【背包dp】

    http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意:有n种纸币面额(a1,a2,...an),每种面额对应有(c1,c2,...cn)张.问这些钱能拼成 ...

  3. CS第三方控件 标签: 总结 2016-04-09 11:51 1398人阅读 评论(27) 收藏

    大家都知道,我现在在做CS的项目,现在是需求频变啊,心里好苦,做了这么久,还是涨了一点点见识的,下面就介绍一下自己最近用到的几款CS的第三方控件. DockPanel 想必大家都用过VS,那么想一下V ...

  4. Java练习 SDUT-1117_求绝对值(选择结构)

    C语言实验--求绝对值(选择结构) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 从键盘上输入任意一个整数,然后输出它 ...

  5. 05Dockerfile简介

    Dockerfile是一个用于构建Docker镜像的文本文件,其中包含了创建Docker镜像的全部指令.基于这些指令,可以使用"docker  build"命令来创建镜像. 一:用 ...

  6. Python基础:17类和实例之一(类属性和实例属性)

    1:类通常在一个模块的顶层进行定义.对于Python来说,声明与定义类是同时进行的. 2:类属性仅与其类相绑定,类数据属性仅当需要有更加“静态”数据类型时才变得有用,这种属性是静态变量.它们表示这些数 ...

  7. php服务端允许跨域访问

    >>php服务端允许跨域访问<< >>同源策略和跨域解决方案<<

  8. Project Euler Problem 23-Non-abundant sums

    直接暴力搞就行,优化的地方应该还是计算因子和那里,优化方法在这里:http://www.cnblogs.com/guoyongheng/p/7780345.html 这题真坑,能被写成两个相同盈数之和 ...

  9. day6_python之configparser_模块

    configparser_模块是为了解析.ini文件的配置 a.ini [xiechao] name=xiechao age=18 is_admin=True salary=1000000.12 [x ...

  10. @noi.ac - 170@ 数数

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 求有多少对 1 ∼ n 的排列 (a, b) 满足 \(m \l ...