P3402 最长公共子序列(nlogn)
P3402 最长公共子序列
题目背景
DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列。
题目描述
经过长时间的摸索和练习,DJL终于学会了怎么求LCS。Johann感觉DJL孺子可教,就给他布置了一个课后作业:
给定两个长度分别为n和m的序列,序列中的每个元素都是正整数。保证每个序列中的各个元素互不相同。求这两个序列的最长公共子序列的长度。
DJL最讨厌重复劳动,所以不想做那些做过的题。于是他找你来帮他做作业。
输入输出格式
输入格式:
第一行两个整数n和m,表示两个数列的长度。
第二行一行n个整数a_1,a_2,…,a_n,保证1≤a_i≤〖10〗^9。
第三行一行m个整数b_1,b_2,…,b_m,保证1≤b_i≤〖10〗^9。
输出格式:
一行一个整数,表示两个数列的最长公共子序列的长度。
输入输出样例
6 6
1 3 5 7 9 8
3 4 5 6 7 8
4
说明
对于40%的数据,n, m≤3000
对于100%的数据,n, m≤300000
分析
对于n方的算法,这道题显然过不去,并且这道题每个数字只出现一次,可以用一个“nlogn”的算法,(加引号的)这个算法只适用于A和B中每个数出现的次数是一个很小的数,这一点题目刚好满足。
具体呢,就是对于在B序列中的元素x,我们在A中找到x的出现位置(在A中的位置)并按降序写下来。然后B中的所有x都有对应的数字,这些数字就是序列C,对C求最长不下降子序列。得到的答案即为A和B的LCS长度。
举个栗子:A={c,a,b,e,d,a,b},B={a,d,c,a,d,b},C={6,2, 5, 1, 6,2, 5, 7,3}
比如B中的a他在A中出现的位置是2,6,按降序后就是6,2;其他的同理。
因为求最长不下降子序列有(nlogn)的算法(http://www.cnblogs.com/mjtcn/p/7197034.html),所以,这也就是nlogn的算法了,再加上预处理出,
这个题这样差不多就完成了,但是,为了方便用map写的,洛谷上只过了7个点,改读入优化,加上inline就过了,可以用哈希写,比map快多了
code
#include<cstdio>
#include<map>
#include<algorithm> using namespace std;
const int MAXN = ;
int f[MAXN]; map<int,int>p;
inline int read()
{
int x = ;char ch = getchar();
while (ch<''||ch>'') ch = getchar();
while (ch>=''&&ch<='') x = x*+ch-'',ch = getchar() ;
return x;
}
inline int search(int l,int r,int x)
{
while (l<r)
{
int mid = (l+r)>>;
if (x<=f[mid]) r = mid;
else l = mid+;
}
return l;
}
int main()
{
int n = read(),m = read(),len = ;
for (int x,i=; i<=n; ++i)
x = read(),p[x] = i;
for (int a,x,i=; i<=m; ++i)
{
a = read();
x = p[a];
if (!x) continue;
if (x>f[len]) f[++len] = x;
else
{
int p = search(,len,x);
f[p] = x;
}
}
printf("%d",len);
return ;
}
P3402 最长公共子序列(nlogn)的更多相关文章
- P3402 最长公共子序列
P3402 最长公共子序列经典问题LCS-->LIS把第一数列转化成1~n,然后将第二个数列映射成1~n中的一些数,然后求第二个数列的LIS即可,然后用Bit求LIS,O(nlogN) //数据 ...
- 【算法】最长公共子序列(nlogn)
转载注明出处:http://blog.csdn.net/wdq347/article/details/9001005 (修正了一些错误,并自己重写了代码) 最长公共子序列(LCS)最常见的算法是时间复 ...
- luogu P3402 最长公共子序列
题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...
- 最长公共子序列 nlogn
先来个板子 #include<bits/stdc++.h> using namespace std; , M = 1e6+, mod = 1e9+, inf = 1e9+; typedef ...
- 洛谷P3402 最长公共子序列
题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...
- 【Luogu】P3402最长公共子序列(LCS->nlognLIS)
题目链接 SovietPower 的题解讲的很清楚.Map或Hash映射后用nlogn求出LIS.这里只给出代码. #include<cstdio> #include<cctype& ...
- 洛谷1439:最长公共子序列(nlogn做法)
洛谷1439:最长公共子序列(nlogn做法) 题目描述: 给定两个序列求最长公共子序列. 这两个序列一定是\(1\)~\(n\)的全排列. 数据范围: \(1\leq n\leq 10^5\) 思路 ...
- LCS最长公共子序列(最优线性时间O(n))
这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
随机推荐
- .net core +mysqlSugar(最为简单的增删改查)
首先建立.net Core API - empty 这个就不说了 然后创建新的Controller 记得添加路由 [Route("api/Users")] 然后在Nuget Pac ...
- 深入剖析javaScript中的深拷贝和浅拷贝
如何区分深拷贝与浅拷贝,简单来说,假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝:我们先看两个简单的案例: //案例1(深拷贝) var a ...
- php 出现空格,换行原因
1.空格:转换成utf-8无bom格式 2.空格:<?php ?>标签结尾有中文,英文空格 3.换行,一个文件中有多个<?php ?>标签,标签间隔中有换行符合
- SQL Server date 设置默认值
根据时间做数据统计计算最讨厌开始和结束时间字段是NULL,为了处理NULL要写很多语句. 那么在数据库设计的时候给一个默认值:0001-01-01和9999-12-31,会给开发人员带来很大的便利. ...
- React 官网列子学习
一个有状态的组件 除了接受输入数据(通过 this.props ),组件还可以保持内部状态数据(通过this.state ).当一个组件的状态数据的变化,展现的标记将被重新调用render() 更新. ...
- cocos2d-x 配置教程
下载cocos2d-x并解压(解压的路径不要带空格,不然以后用cygwin编译工程的时候会出现错误),我的解压到了D:\cocos2d-2.1rc0-x-2.1.2(我的版本是cocos2d-2.1r ...
- linux中python安装
1.查看当前环境中是否存在python安装包 [zyj@localhost ~]$ rpm -qa | grep python gnome-python2-gnome--.el6.x86_64 pyt ...
- linux中配置yum源
1.配置163或者阿里云yum源: 阿里云yum源地址:https://mirrors.aliyun.com/centos/6.9/os/x86_64/Packages/ 阿里云给出的解决办法:htt ...
- MySQL使用一张表的一列更新另一张表的一列
使用MySQL中,在一张表etl_table_field_info上新增了一个字段tgt_table_en_name,该字段的值想从表etl_table_property_info的tgt_table ...
- GIT教程笔记
GIT的工作流程: 先在工作目录中添加.修改文件 一般是在工作目录建立你的工程文件夹,然后通过命令行进入文件夹后 git init 初始化 将需要进行版本管理的文件放入缓存区 git add 文件 ...