CF - LIS on Permutations

Author: Dong Liu

Slow Solution

Time Complexity: O(N2)\mathcal O(N^2)

See here.

Efficient Solution

In the O(N2)\mathcal O(N^2) solution, we increase the DP arrray only if a[i]=b[j]a[i] = b[j], but since both arrays are permutations of length NN, for each a[i]a[i], there must be only one matching element in bb.

Let us create an array pospos where pos[x]pos[x] is the index of xx in aa (a[pos[x]]=xa[pos[x]] = x). Then, we can create another array, cc where c[i]c[i] stores pos[b[i]]pos[b[i]].

Notice that every increasing subsequence x1kx_{1 \dots k} in cc corresponds to a common subsequence between aa and bb. Increasing subsequence c[x1],c[x2],c[xk]c[x_1], c[x_2], \dots c[x_k] corresponds to the the common subsequence b[x1],b[x2],b[xk]b[x_1], b[x_2], \dots b[x_k], which is equivalent to a[c[x1]],a[c[x2]],a[c[xk]]a[c[x_1]], a[c[x_2]], \dots a[c[x_k]]. Thus, the length of the longest common subsequence between aa and bb is the longest increasing subsequence of cc.

Implementation

Time Complexity: O(NlogN)\mathcal O(N\log N)

C++

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, a[N], b[N], c[N], pos[N];
vector<int> lis;
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n;

Java

import java.io.*;
import java.util.*;
public class Main {
Code Snippet: Kattio (Click to expand)
public static void main(String[] args) {
Kattio io = new Kattio();
int n = io.nextInt();
int[] a = new int[n + 1], b = new int[n + 1], c = new int[n + 1],

Python

from bisect import bisect_left
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
# pos is the inverse of a
pos = [0] * (n + 1)
c = [0] * n

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!