bzoj1264: [AHOI2006]基因匹配Match
LCS+树状数组。
O(n^2)的朴素算法显然不可以。
但是根据朴素算法的递推式可知,只有a[i]==b[j]时,f才会更新。
而题目中相等的字符有且只有5个。
对于当前数,枚举它在另一个串的位置,更新答案。
重点是要发现更新的条件减少枚举次数。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100000 + 10; const int maxm = 20000 + 10; int n,n5,res; int f[maxn],a[maxn],b[maxn],p[maxm][6],cnt[maxm]; struct s { int v[maxn]; inline int lowbit(int x) { return x&-x; } void update(int x,int val) { for(int i=x;i<=n5;i+=lowbit(i)) v[i]=max(v[i],val); } int query(int x) { int res=0; for(int i=x;i;i-=lowbit(i)) res=max(res,v[i]); return res; } void init() { memset(v,0,sizeof(v)); } }t; int main() { scanf("%d",&n); n5=n*5; t.init(); for(int i=1;i<=n5;i++) { scanf("%d",&a[i]); p[a[i]][++cnt[a[i]]]=i; } for(int i=1;i<=n5;i++) scanf("%d",&b[i]); for(int i=1,k;i<=n5;i++) for(int j=5;j>=1;j--) { k=p[b[i]][j]; f[k]=max(f[k],t.query(k-1)+1); t.update(k,f[k]); res=max(res,f[k]); } printf("%d\n",res); return 0; }