https://www.luogu.com.cn/problem/P1439
https://class.51nod.com/Html/Textbook/ChapterIndex.html#textbookId=126&chapterId=338
以上兩個都是特例,一個是每個元素不重複,一個是每個元素均有5個。
正確性說明參考:https://www.luogu.com.cn/article/1bcs9052
由於一般情況可能出現多個,就需要類似於上面的處理,倒序是防止一組內選取多個,多個編號是因為只要滿足下標中任意一個均可。
最佳化可以考慮二分或者樹狀陣列(因為離散化過,比較方便了)。
複雜度 \(O(25n\log25n)\)。
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[5*N],n5,s1[N],s2[N],n,t[N][6],f[5*N],c[5*N];
void add(int x,int v){
for(;x<=n5;x+=x&-x)c[x]=max(c[x],v);
}
int sum(int x){
int res=0;
for(;x;x-=x&-x)res=max(res,c[x]);
return res;
}
int main(){
#ifdef LOCAL
freopen("1.txt","r",stdin);
#endif
#ifndef LOCAL
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
#endif
cin>>n;
n*=5;
for(int i=1;i<=n;++i)cin>>s1[i],t[s1[i]][++t[s1[i]][0]]=i;
for(int i=1;i<=n;++i){
cin>>s2[i];
for(int j=5;j;--j)
a[++n5]=t[s2[i]][j];
}
int ans;
for(int i=1;i<=n5;++i){
f[i]=sum(a[i]-1)+1;
add(a[i],f[i]);
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}