【洛谷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();
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328427.html