P3402 最長公共子串行(nlogn)

2021-08-02 08:13:23 字數 1131 閱讀 5364

先看一下資料規模:n<=300000,n^2的做法肯定就要掛掉了,所以用到了這個nlogn的做法。

先介紹一下nlogn的做法:

最長公共子串行 的 nlogn 的演算法本質是 將該問題轉化成 最長增序列(lis),因為 lis 可以用nlogn實現,所以求lcs的時間複雜度降低為 nlogn。

轉化:將lcs問題轉化成lis問題。

假設有兩個序列 s1[ 1~6 ] = , s2[ 1~7 ] = 。

記錄s1中每個元素在s2中出現的位置, 再將位置按降序排列, 則上面的例子可表示為:

loc( a)= , loc( b ) = , loc( c ) = , loc( d ) = 。

將s1中每個元素在s2中的位置按s1中元素的順序排列成乙個序列s3 = 。

在對s3求lis得到的值即為求lcs的答案。

證明略。

再觀察資料,ai<=10^9,那普通的陣列肯定就不行了。然後再看一下題目,每個元素不會重複。所以就產生了兩種處理方法:雜湊 or map(當然大佬會選擇省時的雜湊,我就只能去用map了)。

還要注意乙個問題,在對應中,出現位置是0的直接跳過,因為這是沒有對應的,肯定不是共有的元素啦。

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

map ma;

int n,m;

int s1[300009],s2[300009];

int a[300009],low[300009],len;

int find(int l,int r,int z)

return l;

}int main()

}

printf("%d",len);

return

0;

}

P3402 最長公共子串行

p3402 最長公共子串行 經典問題 lcs lis 沒有重複的值才可以這麼做 把第一數列轉化成1 n,然後將第二個數列對映成1 n中的一些數,然後求第二個數列的lis即可,然後用bit求lis,o nlogn 資料太大,考慮map include include include include i...

洛谷P3402 最長公共子串行

題目背景 djl為了避免成為乙隻鹹魚,來找johann學習怎麼求最長公共子串行。題目描述 經過長時間的摸索和練習,djl終於學會了怎麼求lcs。johann感覺djl孺子可教,就給他布置了乙個課後作業 給定兩個長度分別為n和m的序列,序列中的每個元素都是正整數。保證每個序列中的各個元素互不相同。求這...

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...