• 【模板】加强版最长公共子序列/子串


    其实也不是模板啦...........

    原理

    • 求最长不下降序列是有nlog{n}算法的
    • 数据离散化的应用

    实现

    • 离散化,记(f(x))是由母串的值到母串下标的映射,令所有模式串的值 (x=f(x))
    • 显然母串的下标是严格递增的,那么找最长公共序列就变成了找最长不上升序列, (O(nlog{n}))解决...
    • 同理,找最长公共子串就是找最长的(f(pos)=f(pos-1)+1)的序列了,(O(n))扫描一遍解决...

    记有m个模式串 , 复杂度(O(mnlog{n})),注意常数,跑(10^6)要两秒多,同时也要注意边界。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<bitset>
    #include<ctime>
    
    using namespace std;
    
    
    #define TMP template < class ins >
    #define endl '
    '
    #define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;t++)
    #define ERP(t,a) for(register int t=head[(a)];t;t=e[t].nx)
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;t--)
    typedef long long ll;
    
    TMP inline ins qr(ins tag){
        char c=getchar();
        ins x=0;
        int q=0;
        while(c<48||c>57)
    	q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)
    	x=x*10+c-48,c=getchar();
        return q==-1?-x:x;
    }
    
    #define midd register int mid=(lb+rb)>>1
    const int maxn=100000+15;
    int sav[maxn];
    int cnt;
    int sttd[maxn];
    int in[maxn];
    int par[105][maxn];
    int tk;
    int n,m;
    int ans1,ans2;
    #define more(a,b) (a)=(a)>(b)?(a):(b)
    int stk[maxn];
    int top;
    
    inline int lisan(int x){
        int lb=1,rb=n;
        do{
    	midd;
    	if(sav[mid]<=x)
    	    lb=mid+1;
    	else
    	    rb=mid-1;
        }while(lb<=rb);
        if(sav[rb]!=x)
    	return -1;
        return in[rb];
    }
    
    
    inline int pre(int x){
        int lb=1,rb=n;
        do{
    	midd;
    	if(sav[mid]<=x)
    	    lb=mid+1;
    	else
    	    rb=mid-1;
        }while(lb<=rb);
        return rb;
    }
    
    
    inline int lbound(int lb,int rb,int *p,int x){
        do{
    	midd;
    	if(p[mid]<x)
    	    lb=mid+1;
    	else
    	    rb=mid-1;
        }while(lb<=rb);
        return lb;
    }
    
    
    inline int zixulie(int *p){
        int ret=0;
        stk[0]=0;
        RP(t,1,n){
    	if(p[t]==-1)
    	    continue;
    	if(p[t]>stk[ret])
    	    stk[++ret]=p[t];
    	else
    	    stk[lbound(1,ret,stk,p[t])]=p[t];
        }
        return ret;
    }
    
    
    inline int zichuan(int *p){
        int ret=0;
        int sav=0;
        p[0]=-1;
        RP(t,1,n){
    	if(p[t]==-1){
    	    sav=0;
    	    continue;
    	}
    	if(p[t]==p[t-1]+1)
    	    ++sav;
    	else
    	    more(ret,sav+1),sav=0;
        }
        if(sav)
    	more(ret,sav+1);
        return ret;
    }
    
    
    inline void eff(){
        int t1,t2;
        RP(t,1,m){
    	t1=zixulie(par[t]);
    	t2=zichuan(par[t]);
    	more(ans1,t1);
    	more(ans2,t2);
        }
        cout<<ans1<<endl<<ans2<<endl;
    }
    
    
    inline void init(){
        n=qr(1);
        m=qr(1);
        RP(t,1,n)
    	sav[t]=sttd[t]=qr(1);
        sort(sav+1,sav+n+1);
        RP(t,1,n)
    	in[pre(sttd[t])]=t;
        RP(t0,1,m){
    	int* p=par[t0];
    	RP(t,1,n)
    	    p[t]=lisan(qr(1));
        }
    }
    
    int main(){
        init();
        eff();
        return 0;
    }
    
    

    一百五十行...要是考场上坚持这个想法刚就好了,我还以为这么简单肯定很多人切,原来没有几个.....不过(NOIP_{2018}.RP++)成功....

  • 相关阅读:
    C# 视频监控系列(11):H264播放器——封装API[HikPlayM4.dll]
    php框架
    ExtJS带验证码登录框[新增回车提交]
    ant 读取环境变量的值
    Apache Velocity实现模板化
    23种设计模式概述
    android资源下载
    无序hashset与hashmap让其有序
    PermGen space错误解决方法
    设计模式之代理模式(Proxy)
  • 原文地址:https://www.cnblogs.com/winlere/p/10307955.html
Copyright © 2020-2023  润新知