Logo Universal Online Judge

UOJ

时间限制:4 s 空间限制:1024 MB
统计

题目描述

给定正整数 $K$。请构造两个 $01$ 串 $S,T$,使得它们有恰好 $K$ 个本质不同的最长公共子序列。

我们额外给定参数 $L$,只有你构造的串满足 $\max(\vert S\vert ,\vert T\vert)\le L$ 时才能得分。

输入格式

第一行两个正整数 $K,L$。

输出格式

输出两行,分别表示 $S,T$。

样例 1

1 10000
1
0

样例 2

2 10000
10
01

样例 3

3 10000
101
0110

样例 4

4 10000
1001
0110

每个样例输出的 LCS:

1: (空串)

2: 0 , 1

3: 01 , 10 , 11

4: 00 , 01 , 10 , 11

限制

Subtask #1 (10 分):$L=10^4,K<\frac{L}{2}$。

Subtask #2 (15 分):$L=10^4,K\le 10^9,K=\binom{k}{3}$。

Subtask #3 (20 分):$L=10^4,K\le 10^6$。

Subtask #4 (20 分):$L=10^4,K\le 10^9$。

Subtask #5 (15 分):$K=2^k$。

Subtask #6 (20 分):无特殊限制。

对于所有数据,$K\le 10^{15},L\ge 10^3$。

检查

运行下面的代码,输入 $S,T$。设本质不同 LCS 个数为 $C$,它会输出 $\min(10^{15}+1,C)$。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=int(a),_=int(b);i<=_;++i)
#define per(i,a,b) for(int i=int(a),_=int(b);i>=_;--i)
using namespace std;
typedef long long ll;
const ll inf=ll(1e15)+1;
struct node
{
    int len;
    ll cnt;
    node(int len=0,ll cnt=1):len(len),cnt(cnt){}
    node F(){return node{len+1,cnt};}
    node operator+(node o)
    {
        if(len==o.len)return node{len,min(inf,cnt+o.cnt)};
        return len>o.len?*this:o;
    }
};
const int N=1e4+10;
int n,m,a[N][2],b[N][2];
char s[N],t[N];
node dp[3][N];
void init(char *s,int a[N][2],int &n)
{
    n=strlen(s+1);
    rep(i,1,n)
    {
        rep(j,0,1)a[i][j]=a[i-1][j];
        a[i][s[i]-'0']=i;
    }
}
int main()
{
    scanf("%s%s",s+1,t+1);
    init(s,a,n);
    init(t,b,m);
    rep(i,1,n)
    {
        rep(j,0,m)dp[s[i]-'0'][j]=dp[2][j],dp[2][j]=node();
        rep(k,0,1)if(a[i][k])
        rep(j,1,m)if(b[j][k])
        dp[2][j]=dp[2][j]+dp[k][b[j][k]-1].F();
    }
    cout<<"cnt="<<dp[2][m].cnt<<",len="<<dp[2][m].len<<endl;
    return 0; 
}