最小序列
题目描述
一个包含n个数的序列A(所有的数各不相等),首先定义一个B: Bi = max{Bj} + 1 {Aj < Ai, j < i} 然后,对于任意序列,若它满足以下条件,我们则称之为K号序列: 1. 该序列长度为K,并且是A的子序列。 2. 该序列在A中对应的B值为连续自然数。 3. 该序列在所有满足条件1,2的序列中字典序最小。
举个例子: 序列A: 2 6 7 3 4 5 1
B值: 1 2 3 2 3 4 1
长度为3且满足条件1,2的序列有{2,6,7}和{2,3,4}和{3,4,5},但{2,3,4}字典序最小,因此3号序列为{2,3,4}。 Your Task 给你一个长度为N的序列,再给你M个形如{i,j}的询问,要你求出i号序列与j号序列的最长公共子序列的长度。 输入文件 第一行 N M 分别为序列长度,询问个数 第二行 N个数描述序列A 接下来M行每行一个询问 i j 输出文件 M行,每行一个数对应一个询问的答案。 样例输入
7 2
2 6 7 3 4 5 1
3 4
3 1 样例输出 3 0
数据约定 10%的数据中,N ,M≤ 10; 20%的数据中,N ,M≤ 1000; 100%的数据中,N ,M≤ 500000; 保证询问合法,即 1 <= i, j <= max{B}。
题目来自清北学堂的NOI模拟
看了一下 挺有意思的
首先B值肯定是 到这个点最长上升子序列的值 通过NlogN的最长上升子序列的算法 可以做出一颗树 从根到达每个节点i 的路径就是以i结束 的 最长上升子序列 顺便给结点i赋一个点权 代表i的深度(以i结尾最长子序列的长度) 至于做树的方法就是K[i]表示 i长的最长子序列结尾的最小值 对于当前操作的数now找到他的位置 (k[i]<now<k[i+1]) 从K[i]往now]连一条边 然后更新k[i+1]=now
对于每个询问Q(i,j)来说 就是寻找i j的最近公共祖先的深度 而且是一个离线询问 targan算法就可以做到