【洛谷P4608】【FJOI2016】—所有公共子序列问题(序列自动机+DP+高精度)
对两个串建出序列自动机之后直接即可
由于答案很大,需要写个高精度
由于答案很大,要写压位高精,否则会
由于空间直接开不下,于是写了个存状态
由于出题人很神奇,输出方案的话必须要在开头输出一个空串
#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();
}