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
",res);    
    return 0;    
}
原文地址:https://www.cnblogs.com/invoid/p/5669684.html