码迷,mamicode.com
首页 > 其他好文 > 详细

「FJOI2016」所有公共子序列问题

时间:2020-04-03 21:46:35      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:结构体   ace   问题   r++   字典   char   line   opera   ==   

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9;
const int N=3020;
const int L=58;
const int K=25;
int nxt1[N][L],nxt2[N][L];
char sta[N];
int top=-1;
ll ans;
int la,lb,k;
char a[N],b[N];
struct Big{//压位结构体 
    int cur;
    ll *s;
    void init(){
        s=new long long[20];
        for(int i=0;i<20;i++) s[i]=0;
        cur=0;
    }
    void put(){
        printf("%lld",s[cur]);
        for(int i=cur-1;i>=0;i--) printf("%09lld",s[i]);
    }
    void add(ll k){
        s[0]+=k;
        int i=0;
        while(s[i]>=mod) s[i+1]+=s[i]/mod,s[i++]%=mod;
        while(s[cur+1]) cur++;
    }
    void Add(const Big& o){
        ll i,r=max(cur,o.cur);
        for(int i=0;i<=r;i++){
            s[i]+=o.s[i];
            if(s[i]>=mod) s[i+1]+=s[i]/mod,s[i]%=mod;
        }
        cur=min(r+3,19ll);while(cur&&s[cur]==0) cur--;
    }
}dp[N][N];
bool vis[N][N];
void build1()
{//建造序列自动机 
    memset(nxt1[la],-1,sizeof nxt1[la]);
    for(int i=la;i;i--)
	{
        memcpy(nxt1[i-1],nxt1[i],sizeof nxt1[i]);
        nxt1[i-1][a[i]-‘A‘]=i;
    }
}
void build2()
{
    memset(nxt2[lb],-1,sizeof nxt2[lb]);
    for(int i=lb;i;i--){
        memcpy(nxt2[i-1],nxt2[i],sizeof nxt2[i]);
        nxt2[i-1][b[i]-‘A‘]=i;
    }
}
void dfs2(int x,int y)
{//dfs 
    if(vis[x][y]) return;
    vis[x][y]=1;
    dp[x][y].init();
    dp[x][y].add(1);
    for(int i=0;i<=57;i++)
	{
        if(nxt1[x][i]!=-1&&nxt2[y][i]!=-1) 
		{
        dfs2(nxt1[x][i],nxt2[y][i]);
        dp[x][y].Add(dp[nxt1[x][i]][nxt2[y][i]]);
        }
    }
}
ll dfs1(int x,int y)
{
    printf("%s\n",sta);
    ll cnt=1;
    for(int i=0;i<=57;i++)
	{
        if(nxt1[x][i]!=-1&&nxt2[y][i]!=-1) 
		{
        sta[++top]=i+‘A‘;
        cnt+=dfs1(nxt1[x][i],nxt2[y][i]);
        sta[top--]=‘ ‘;
        }
    }
    return cnt;
}
int main()
{
    scanf("%d%d",&la,&lb);
    scanf("%s",a+1);scanf("%s",b+1);    
    scanf("%d",&k);
    build1();build2();
    if(k==1) 
    //字典序输出LCS,并最后输出总个数 
	{    
    dfs1(0,0);
    }
    dfs2(0,0);
    dp[0][0].put();
    return 0;
}

  

#include<bits/stdc++.h>
#define reg register
typedef long long ll;
using namespace std;
const int MN=3011;
const int BASE=1e9;
int n,m,typ,top,cnt,nxt1[MN][52],nxt2[MN][52];
char S[MN],T[MN],stk[MN];
inline int trans(char ch){
	if(ch<=‘Z‘)return ch-‘A‘;
	return ch-‘a‘+26;
}
inline char retrans(int x){
	if(x<26)return x+‘A‘;
	return x+‘a‘-26;
}
void dfs1(int st1,int st2)
{
	puts(stk+1);
	cnt++;
	for(reg int i=0;i<52;i++)
		if((~nxt1[st1][i])&&(~nxt2[st2][i]))
			stk[++top]=retrans(i),
			dfs1(nxt1[st1][i],nxt2[st2][i]),
			stk[top--]=‘\0‘;
}
struct BigInt{
	int len;ll d[20];
	inline void init(){len=d[1]=1;}
	inline BigInt operator+(BigInt a){
		len=max(len,a.len);
		for(reg int i=1;i<=len;i++)
			d[i]+=a.d[i],d[i+1]+=d[i]/BASE,d[i]%=BASE;
		while(d[len+1])len++;
		return *this;
	}
}c[MN][MN];
bool vis[MN][MN];
void dfs2(int st1,int st2)
{
	if(vis[st1][st2])
	     return;
	vis[st1][st2]=true;
	c[st1][st2].init();
	for(reg int i=0;i<52;i++)
		if((~nxt1[st1][i])&&(~nxt2[st2][i]))
			dfs2(nxt1[st1][i],nxt2[st2][i]),
			c[st1][st2]=c[st1][st2]+c[nxt1[st1][i]][nxt2[st2][i]];
}
int main()
{
	scanf("%d%d%s%s%d",&n,&m,S+1,T+1,&typ);
	memset(nxt1[n],-1,52<<2);
	for(reg int i=n;i;i--)
		memcpy(nxt1[i-1],nxt1[i],52<<2),
		nxt1[i-1][trans(S[i])]=i;
	memset(nxt2[m],-1,52<<2);
	for(reg int i=m;i;i--)
		memcpy(nxt2[i-1],nxt2[i],52<<2),
		nxt2[i-1][trans(T[i])]=i;
	if(typ)
	{
	dfs1(0,0),printf("%d\n",cnt);return 0;
	}
	dfs2(0,0);
	printf("%d",c[0][0].d[c[0][0].len]);
	for(reg int i=c[0][0].len-1;i;i--)
		printf("%09d",c[0][0].d[i]);
	return 0;
}

  

「FJOI2016」所有公共子序列问题

标签:结构体   ace   问题   r++   字典   char   line   opera   ==   

原文地址:https://www.cnblogs.com/cutemush/p/12628902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!