//洛谷p1436 (模板)
我們定義對映f(ai)=i,那麼兩個排列可以轉換為(f(a1),f(a2),...,f(an))=(1,2,...,n)和(f(b1),f(b2),...,f(bn)),我們進行這樣的轉換之後,就把本題轉換為求最長上公升子串行的長度的題目了。
最長上公升子串行存在o(n log n)時間複雜度的演算法,概述如下:
考慮兩個數a[x]和a[y],若x按照g[i]==k分類,記錄g[i]==k的所有i的最小值,g有兩個特點:
1)f[i]在計算過程中單調不公升
2)f陣列是有序的,g[i]<=g[i+1]
根據這些性質,可以方便地求解:
1)設當前求出的lis(最長上公升子串行的簡稱,以後同此)長度為ans(初始值為1),當前元素為a[x]
2)如果a[x]>g[ans],直接加入f陣列的末尾,且ans++;否則在f陣列中二分查詢,找到第乙個比a[x]小的數字g[k](使用二分查詢實現),g[k+1]=a[x],這樣做保證a[x]<=g[k+1](根據性質1,2)
3)最後的ans即為答案
**如下:
#include#include#include
using
namespace
std;
const
int maxn=100010
;int n,a[maxn],f[maxn],g[maxn],ans=1
,cur;
inline
int bs(int k,int l,int
r)
returnl;}
//二分查詢 bs(k,l,r)表示在[l,r]中尋找比k大的最小的數
intmain()
//dp處理,並記錄ans
printf("%d"
,ans);
return0;
}
模板 最長公共子串行
以洛谷p1439為例 n可以開到1e5 tle mle 編譯都過不了 讀入a陣列後雜湊一波,然後將b陣列的值在雜湊陣列裡找到對應值並替換,於是變成了求b陣列最長上公升子串行 玄學 可以使用二分,時間複雜度o nlogn ac include include include include using...
模板 最長公共子串行
題源 問題能轉化成二分求最長上公升子串行 lower bound 返回第乙個大於等於查詢值的位置 lower bound 返回第乙個小於查詢值的位置 binary search 返回判斷查詢值在不在的 bool 值 include define numm ch 48 define pd putcha...
luogu 模板 最長公共子串行
給出1 n的兩個排列p1和p2,求它們的最長公共子串行。輸入格式 第一行是乙個數n,接下來兩行,每行為n個數,為自然數1 n的乙個排列。輸出格式 乙個數,即最長公共子串行的長度 普通求最長公共子串行的dp i j 的方法肯定不行 但這裡每個元素的值都是確定的了.以f i 表示i長度為i的最長公共子串...