• 【洛谷P4608】【FJOI2016】—所有公共子序列问题(序列自动机+DP+高精度)


    传送门

    对两个串建出序列自动机之后直接n2dpn^2dp即可

    由于答案很大,需要写个高精度
    由于答案很大,要写压位高精,否则会TT
    由于空间直接开不下,于是写了个mapmap存状态
    由于出题人很神奇,输出方案的话必须要在开头输出一个空串

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>
    template<class T>inline void chemx(T &a,T b){a<b?a=b:0;}
    template<class T>inline void chemn(T &a,T b){a>b?a=b:0;}
    struct node{
    	static cs int mod=1e9;
    	int a[30],n;
    	node(){memset(a,0,sizeof(a));n=0;}
    	friend inline node operator +(cs node &a,cs node &b){
    		node c;
    		c.n=max(a.n,b.n);
    		for(int i=1;i<=c.n;i++){
    			c.a[i]+=a.a[i]+b.a[i];
    			c.a[i+1]+=c.a[i]/mod,c.a[i]%=mod;
    		}
    		while(c.a[c.n+1])c.n++,c.a[c.n+1]+=c.a[c.n]/mod,c.a[c.n]%=mod;
    		return c;
    	}
    	inline void out(){
    		cout<<a[n];
    		for(int i=n-1;i;i--)printf("%09d",a[i]);puts("");
    	}
    };
    node one;
    cs int N=3050;
    int nxt[2][N][52],k;
    inline void init_nxt(int id,int *s,int n){
    	for(int i=n;i;i--){
    		for(int j=0;j<52;j++)if(j!=s[i])
    		nxt[id][i-1][j]=nxt[id][i][j];
    		nxt[id][i-1][s[i]]=i;
    	}
    }
    vector<char> now;
    void dfs1(int p1,int p2,int ok){
    	if(ok){for(char &s:now)putchar(s);puts("");}
    	for(int i=0;i<26;i++)
    	if(nxt[0][p1][i]&&nxt[1][p2][i])
    		now.pb('A'+i),dfs1(nxt[0][p1][i],nxt[1][p2][i],1),now.pop_back();
    	for(int i=26;i<52;i++)
    	if(nxt[0][p1][i]&&nxt[1][p2][i])
    		now.pb('a'+i-26),dfs1(nxt[0][p1][i],nxt[1][p2][i],1),now.pop_back();
    }
    map<int,node> f[N];
    node dfs2(int p1,int p2){
    	if(f[p1].count(p2))return f[p1][p2];
    	node res=one;
    	for(int i=0;i<52;i++)
    	if(nxt[0][p1][i]&&nxt[1][p2][i])
    	res=res+dfs2(nxt[0][p1][i],nxt[1][p2][i]);
    	return f[p1][p2]=res;
    }
    int n,m,a[N];
    char s[N];
    int main(){
    	one.n=1,one.a[1]=1;
    	n=read(),m=read();
    	scanf("%s",s+1);
    	for(int i=1;i<=n;i++)
    	if('A'<=s[i]&&s[i]<='Z')a[i]=s[i]-'A';
    	else a[i]=s[i]-'a'+26;
    	init_nxt(0,a,n);
    	scanf("%s",s+1);
    	for(int i=1;i<=m;i++)
    	if('A'<=s[i]&&s[i]<='Z')a[i]=s[i]-'A';
    	else a[i]=s[i]-'a'+26;
    	init_nxt(1,a,m);
    	k=read();
    	if(k==1)dfs1(0,0,1);
    	dfs2(0,0).out();
    }
    
  • 相关阅读:
    《常微分方程,王高雄》 习题 1.5,1.8(2)
    微分方程及边值问题:计算与建模 习题1.17-1.31
    打造自己备份的系统镜像
    打造自己备份的系统镜像
    ★一名“标题党”自我修炼的10大技巧
    ★一名“标题党”自我修炼的10大技巧
    ★数学上最大的数是多少?
    ★不容错过的PPT教程!
    ★不容错过的PPT教程!
    【★】电子产品降价的3大原因!
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328427.html
Copyright © 2020-2023  润新知