Problem:
Shortest Common Non-Subsequence
A subsequence of a sequence $P$ is a sequence that can be derived from the original sequence $P$ by picking up some or no elements of $P$ preserving the order. For example, "
ICPC
" is a subsequence of "
MICROPROCESSOR
".
A common subsequence of two sequences is a subsequence of both sequences. The famous longest common subsequence problem is finding the longest of common subsequences of two given sequences.
In this problem, conversely, we consider
the shortest common non-subsequence problem
: Given two sequences consisting of 0 and 1, your task is to find the shortest sequence also consisting of 0 and 1 that is a subsequence of
neither
of the two sequences.
Input
The input consists of a single test case with two lines. Both lines are sequences consisting only of 0 and 1. Their lengths are between 1 and 4000, inclusive.
Output
Output in one line the shortest common non-subsequence of two given sequences. If there are two or more such sequences, you should output the lexicographically smallest one. Here, a sequence $P$ is lexicographically smaller than another sequence $Q$ of the same length if there exists $k$ such that $P_1 = Q_1, ... , P_{k-1} = Q_{k-1}$, and $P_k < Q_k$, where $S_i$ is the $i$-th character of a sequence $S$.
Sample Input 1
0101
1100001
Sample Output 1
0010
Sample Input 2
101010101
010101010
Sample Output 2
000000
Sample Input 3
11111111
00000000
Sample Output 3
01

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 4444;
int dp[maxn][maxn];
char P[maxn], Q[maxn];
int nextp[maxn][2], nextq[maxn][2];
int vis[maxn][maxn];

int main()
{
    while(scanf("%s%s", P + 1, Q + 1) != EOF)
    {
        int lp = strlen(P + 1);
        int lq = strlen(Q + 1);

        // 直接在每个字符串末尾添加上0 1 0 1
        // 这样无论如何匹配就不会出问题了
        nextp[lp + 2][0] = nextp[lp + 2][1] = nextp[lp + 1][0] = nextp[lp + 1][1] = lp + 1;
        nextq[lq + 2][0] = nextq[lq + 2][1] = nextq[lq + 1][0] = nextq[lq + 1][1] = lq + 1;
        for(int i = lp; i >= 0; i--)
        {
            if(P[i] == '0') nextp[i][0] = i;
            else nextp[i][0] = nextp[i + 1][0];

            if(P[i] == '1') nextp[i][1] = i;
            else nextp[i][1] = nextp[i + 1][1];
        }
        for(int i = lq; i >= 0; i--)
        {
            if(Q[i] == '0') nextq[i][0] = i;
            else nextq[i][0] = nextq[i + 1][0];

            if(Q[i] == '1') nextq[i][1] = i;
            else nextq[i][1] = nextq[i + 1][1];
        }
        memset(dp, 0x3f, sizeof(dp));
        dp[0][0] = 0;
        // next记录下一个非自身的0
        // 这个有一个特判就是最后一个字母可以代表任何数
        // 并且这个末尾的数下一个一定指向自己
        for(int i = 0; i <= lp + 1; i++)
            for(int j = 0 ; j <= lq + 1; j++)
                if(P[i] == Q[j] ||  i == lp + 1 || j == lq + 1)
                {
                    int np0 = nextp[i + 1][0];
                    int nq0 = nextq[j + 1][0];
                    int np1 = nextp[i + 1][1];
                    int nq1 = nextq[j + 1][1];
                    dp[np0][nq0] = min(dp[np0][nq0], dp[i][j] + 1);
                    dp[np1][nq1] = min(dp[np1][nq1], dp[i][j] + 1);
                }
        // 最后倒推的时候也要特判啊.....
        memset(vis, 0x3f, sizeof(vis));
        vis[lp + 1][lq + 1] = 0;
        for(int i = lp + 1; i >= 0; i--)
            for(int j = lq + 1 ; j >= 0; j--)
                if(P[i] == Q[j] ||  i == lp + 1 || j == lq + 1)
                {
                    int np0 = nextp[i + 1][0];
                    int nq0 = nextq[j + 1][0];
                    int np1 = nextp[i + 1][1];
                    int nq1 = nextq[j + 1][1];
                    if(dp[np0][nq0] == dp[i][j] + 1) vis[i][j] = min(vis[i][j], vis[np0][nq0] + 1);
                    if(dp[np1][nq1] == dp[i][j] + 1) vis[i][j] = min(vis[i][j], vis[np1][nq1] + 1);
                    //if(vis[i][j]) printf("vis[%d][%d] is true!\n", i ,j);
                }
        int len = dp[lp + 1][lq + 1];
        int curp = 0, curq = 0;
        for(int i = 0; i < len; i++)
        {
            // 优先使用0
            int np0 = nextp[curp + 1][0];
            int nq0 = nextq[curq + 1][0];
            int np1 = nextp[curp + 1][1];
            int nq1 = nextq[curq + 1][1];

            //printf("vis[%d][%d] :%d\n", curp, curq, vis[curp][curq]);
            if(vis[np0][nq0] == len - i - 1)
            {
                curp = np0, curq = nq0;
                putchar('0');
            }
            else
            {
                curp = np1, curq = nq1;
                putchar('1');
            }
        }
        putchar('\n');
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 157872
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
vector<vector<int>>calc(string s){
  int n=s.size();
  vector ret(2,vector<int>(n+2,n+1));
  vector<vector<int>>idx(2);
  rep(i,n)idx[s[i]-'0'].emplace_back(i);
  idx[0].emplace_back(n);
  idx[1].emplace_back(n);
  rep(i,2){
    rep(j,n){
      ret[i][j]=1+*lower_bound(idx[i].begin(),idx[i].end(),j);
    }
  }
  return ret;
}
string s,t;
int n,m;
constexpr int inf=1<<30;
struct S{
  int len,prev_ch,prev_i,prev_j;
};
signed main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>s>>t;
  n=s.size(),m=t.size();
  vector dp(n+2,vector<S>(m+2,{inf,-1,-1,-1}));
  dp[0][0]={0,-1,-1,-1};
  queue<pair<int,int>>que;
  que.push({0,0});
  auto pre_s=calc(s),pre_t=calc(t);
  while(!que.empty()){
    auto[i,j]=que.front();
    que.pop();
    rep(ch,2){
      int ni=pre_s[ch][i],nj=pre_t[ch][j];
      if(dp[i][j].len+1<dp[ni][nj].len){
        dp[ni][nj]={dp[i][j].len+1,ch,i,j};
        que.push({ni,nj});
      }
    }
  }
  //rep(i,n+2)rep(j,m+2)cout<<dp[i][j].len<<" \n"[j+1==m+2];
  int x=n+1,y=m+1;
  string ans;
  while(!(x==0&&y==0)){
    ans+='0'+dp[x][y].prev_ch;
    int xx=dp[x][y].prev_i,yy=dp[x][y].prev_j;
    x=xx,y=yy;
  }
  reverse(ans.begin(),ans.end());
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 140
memory_kb: 254080
final_rank: 15

code_snippet: #include<iostream>
#include<cstring>
using namespace std;
int n,m,nxt[2][4005][2];//第一个字符串第i个字符后最近的0/1位置 
int dp[4005][4005];//
char path[4005][4005];
string str[2];
int dfs(int x,int y){
	if(x==str[0].length()&&y==str[1].length()){
		dp[x][y]=0; 
		return 0;
	}
	if(dp[x][y]!=-1)return dp[x][y];
	int step0=dfs(nxt[0][x][0],nxt[1][y][0]);//如果下一个字符选的是0，递归判断最短公共子序列长度
	int step1=dfs(nxt[0][x][1],nxt[1][y][1]);//如果下一个字符选的是1，递归判断最短公共子序列长度
	if(step0<=step1) path[x][y]=0;
	else path[x][y]=1;	
	dp[x][y]=min(step0,step1)+1;
	return dp[x][y];
}
void print(int x,int y){
	if(x==str[0].length()&&y==str[1].length())
		return;
	putchar(path[x][y]+'0');
	print(nxt[0][x][path[x][y]],nxt[1][y][path[x][y]]);
}
void init(int id){
	str[id]=" "+str[id];
	int len=str[id].length();	
	nxt[id][len][0]=nxt[id][len][1]=len;
	nxt[id][len-1][0]=nxt[id][len-1][1]=len;
	for(int i=len-2;i>=0;i--){
		nxt[id][i][0]=nxt[id][i+1][0];
		nxt[id][i][1]=nxt[id][i+1][1];	
		nxt[id][i][str[id][i+1]-'0']=i+1;	
	}
} 
int main(){
//	freopen("substr.in","r",stdin);
//	freopen("substr.out","w",stdout);	
   // cin>>n>>m;
    cin>>str[0]>>str[1]; 
    init(0);init(1);
    memset(dp,-1,sizeof(dp));
	dfs(0,0);
    print(0,0);
    printf("\n");
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 81900
final_rank: 3

code_snippet: #include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> 
using namespace std;
 
const int N = 4000+10;
 
char a[N];
char b[N];
int nxta[N][2];
int nxtb[N][2];
int dp[N][N];
int f[N][N];
int lena,lenb;
 
vector<int>ans;
 
int dfs(int x,int y)
{
	if(x==lena+1&&y==lenb+1) return 0;
	if(dp[x][y]) return dp[x][y];
	
	int tmp1=dfs(nxta[x][0],nxtb[y][0]);
    int tmp2=dfs(nxta[x][1],nxtb[y][1]);
   
    //根据题目要求，选择长度较小的为答案 
    if(tmp1<=tmp2) f[x][y]=0;
    else f[x][y]=1;
    
    return dp[x][y]=min(tmp1,tmp2)+1;
}
 
void getans(int x,int y)
{
	if(x==lena+1&&y==lenb+1) return;
	int tmp=f[x][y];
	ans.push_back(tmp);
	getans(nxta[x][tmp],nxtb[y][tmp]);
}
 
int main()
{
	scanf("%s%s",a+1,b+1);
	lena=strlen(a+1);
	lenb=strlen(b+1);
	
	nxta[lena+1][0]=nxta[lena+1][1]=lena+1;
	nxtb[lenb+1][0]=nxtb[lenb+1][1]=lenb+1;
	for(int i=lena;i>=0;i--)
	{
		nxta[i][0]=nxta[i+1][0];
	    nxta[i][1]=nxta[i+1][1];
	    if(a[i+1]=='0') nxta[i][0]=i+1;
	    else nxta[i][1]=i+1; 
	}
	
	for(int i=lenb;i>=0;i--)
	{
		nxtb[i][0]=nxtb[i+1][0];
	    nxtb[i][1]=nxtb[i+1][1];
	    if(b[i+1]=='0') nxtb[i][0]=i+1;
	    else nxtb[i][1]=i+1; 
	}
	
	dfs(0,0);
	getans(0,0);
	for(int i=0;i<ans.size();i++)
	printf("%d",ans[i]);
    printf("\n");
}
accuracy: 1
time_ms: 50
memory_kb: 127512
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    string s1, s2;
    cin >> s1 >> s2;
    int n1 = s1.size();
    int n2 = s2.size();

    vector<int> next0_s1(n1 + 1, n1);
    vector<int> next1_s1(n1 + 1, n1);
    vector<int> next0_s2(n2 + 1, n2);
    vector<int> next1_s2(n2 + 1, n2);

    for (int i = n1 - 1; i >= 0; i--) {
        if (s1[i] == '0') {
            next0_s1[i] = i;
            next1_s1[i] = next1_s1[i + 1];
        } else {
            next1_s1[i] = i;
            next0_s1[i] = next0_s1[i + 1];
        }
    }

    for (int i = n2 - 1; i >= 0; i--) {
        if (s2[i] == '0') {
            next0_s2[i] = i;
            next1_s2[i] = next1_s2[i + 1];
        } else {
            next1_s2[i] = i;
            next0_s2[i] = next0_s2[i + 1];
        }
    }

    vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1, 0));
    vector<vector<char>> cho(n1 + 1, vector<char>(n2 + 1, 0));

    dp[n1][n2] = 1;
    cho[n1][n2] = '0';

    for (int i = n1; i >= 0; i--) {
        for (int j = n2; j >= 0; j--) {
            if (i == n1 && j == n2) continue;

            int ns0_i = (i < n1) ? next0_s1[i] : n1;
            int nt0_j = (j < n2) ? next0_s2[j] : n2;
            int f0;
            if (ns0_i == n1 && nt0_j == n2) {
                f0 = 1;
            } else if (ns0_i == n1) {
                f0 = 1 + dp[n1][nt0_j + 1];
            } else if (nt0_j == n2) {
                f0 = 1 + dp[ns0_i + 1][n2];
            } else {
                f0 = 1 + dp[ns0_i + 1][nt0_j + 1];
            }

            int ns1_i = (i < n1) ? next1_s1[i] : n1;
            int nt1_j = (j < n2) ? next1_s2[j] : n2;
            int f1;
            if (ns1_i == n1 && nt1_j == n2) {
                f1 = 1;
            } else if (ns1_i == n1) {
                f1 = 1 + dp[n1][nt1_j + 1];
            } else if (nt1_j == n2) {
                f1 = 1 + dp[ns1_i + 1][n2];
            } else {
                f1 = 1 + dp[ns1_i + 1][nt1_j + 1];
            }

            if (f0 <= f1) {
                dp[i][j] = f0;
                cho[i][j] = '0';
            } else {
                dp[i][j] = f1;
                cho[i][j] = '1';
            }
        }
    }

    string res = "";
    int i = 0, j = 0;
    while (i <= n1 && j <= n2) {
        if (i == n1 && j == n2) {
            res += cho[i][j];
            break;
        }
        char c = cho[i][j];
        res += c;
        if (c == '0') {
            int ns = (i < n1) ? next0_s1[i] : n1;
            int nt = (j < n2) ? next0_s2[j] : n2;
            if (ns == n1 && nt == n2) {
                break;
            }
            if (ns == n1) {
                i = n1;
                j = nt + 1;
            } else if (nt == n2) {
                i = ns + 1;
                j = n2;
            } else {
                i = ns + 1;
                j = nt + 1;
            }
        } else {
            int ns = (i < n1) ? next1_s1[i] : n1;
            int nt = (j < n2) ? next1_s2[j] : n2;
            if (ns == n1 && nt == n2) {
                break;
            }
            if (ns == n1) {
                i = n1;
                j = nt + 1;
            } else if (nt == n2) {
                i = ns + 1;
                j = n2;
            } else {
                i = ns + 1;
                j = nt + 1;
            }
        }
    }

    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 81628
final_rank: 4

code_snippet: // 突然反应过来如果反向dp不就能满足字典序了吗！
#include <bits/stdc++.h>
using namespace std;
const int NN = 4002;
struct Node {
	short lth, prec, prex, prey;
};
Node D[2][NN][NN]; // D[c][x][y]: s1[x, n1) & s2[y, n2), 要求首c
Node merge(short i, short j) {
	short lth0 = D[0][i][j].lth + 1, lth1 = D[1][i][j].lth + 1;
	return (lth0 > lth1 ? Node{lth1, 1, i, j} : Node{lth0, 0, i, j});
}
int main(){
	ios::sync_with_stdio(false), cin.tie(0);
	string s1, s2;
	cin >> s1 >> s2;
	short n1 = s1.size(), n2 = s2.size();
	D[0][n1][n2] = {1, -1, -1, -1}, D[1][n1][n2] = {1, -1, -1, -1};
	for (short i = n1 - 1; i >= 0; --i) {
		short c = s1[i] - '0';
		D[1-c][i][n2] = D[1-c][i+1][n2];
		D[c][i][n2] = merge(i+1, n2);
	}
	for (short j = n2 - 1; j >= 0; --j) {
		short c = s2[j] - '0';
		D[1-c][n1][j] = D[1-c][n1][j+1];
		D[c][n1][j] = merge(n1, j+1);
	}
	for (short i = n1 - 1; i >= 0; --i) for (short j = n2 - 1; j >= 0; --j) {
		short c1 = s1[i] - '0', c2 = s2[j] - '0';
		if (c1 != c2) D[1-c1][i][j] = D[1-c1][i+1][j], D[1-c2][i][j] = D[1-c2][i][j+1];
		else D[1-c1][i][j] = D[1-c1][i+1][j+1], D[c1][i][j] = merge(i+1, j+1);
	}
	short c = (D[0][0][0].lth > D[1][0][0].lth ? 1 : 0), x = 0, y = 0;
	string ans = "";
	while (c != -1) {
		ans += char(c + '0');
		Node& pt = D[c][x][y];
		c = pt.prec, x = pt.prex, y = pt.prey;
	}
	cout << ans << "\n";
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 253608
final_rank: 12

code_snippet: #line 1 "main.cpp"
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s, t; cin>> s >> t;
    ranges::reverse(s);
    ranges::reverse(t);
    array<vector<short>, 2> rs, rt;
    rs[0].push_back(0);
    rs[1].push_back(0);
    for(short i = 0; i < ssize(s); i++) {
        rs[s[i]-'0'].push_back(i+1);
    }
    rs[0].push_back(ssize(s)+1);
    rs[1].push_back(ssize(s)+1);
    rt[0].push_back(0);
    rt[1].push_back(0);
    for(short i = 0; i < ssize(t); i++) {
        rt[t[i]-'0'].push_back(i+1);
    }
    rt[0].push_back(ssize(t)+1);
    rt[1].push_back(ssize(t)+1);
    short ss = ssize(s), st = ssize(t);
    s.clear(); s.shrink_to_fit();
    t.clear(); t.shrink_to_fit();
    constexpr short INF = 1<<14;
    vector dp(ss+2, vector(st+2, INF));
    dp[0][0] = 0;
    for(short i = 0; i < ss+2; i++) for(short j = 0; j < st+2; j++) {
        if(i == ss+1 && j == st+1) continue;
        for(short c : {0, 1}) {
            short ni = i;
            if(i < ss+1) ni = *ranges::upper_bound(rs[c], i);
            short nj = j;
            if(j < st+1) nj = *ranges::upper_bound(rt[c], j);
            if(dp[i][j]+1 < dp[ni][nj]) {
                dp[ni][nj] = dp[i][j]+1;
            }
        }
    }
    for(short i = ss+1; i >= 0; i--) for(short j = st+1; j >= 0; j--) {
        if(i > 0 && dp[i-1][j] > dp[i][j]) dp[i-1][j] = dp[i][j];
        if(j > 0 && dp[i][j-1] > dp[i][j]) dp[i][j-1] = dp[i][j];
    }
    int len = dp.back().back();
    string ans;
    vector<pair<short, short>> cur = {{ss+1, st+1}};
    for(short _ = 0; _ < len; _++) {
        array<vector<pair<short, short>>, 2> ncur;
        for(auto [i, j] : cur) {
            for(short c : {0, 1}) {
                short ni = i;
                if(i > 0) ni = *prev(ranges::lower_bound(rs[c], i));
                short nj = j;
                if(j > 0) nj = *prev(ranges::lower_bound(rt[c], j));
                if(dp[ni][nj]+1 == dp[i][j]) {
                    ncur[c].emplace_back(ni, nj);
                }
            }
        }
        for(short c : {0, 1}) {
            if(!ncur[c].empty()) {
                ans.push_back((char)('0'+c));
                ranges::sort(ncur[c]);
                ncur[c].erase(ranges::unique(ncur[c]).begin(), ncur[c].end());
                cur.swap(ncur[c]);
                break;
            }
        }
    }
    assert(ssize(cur) == 1 && cur[0] == make_pair((short)0, (short)0));
    cout << ans << '\n';
}
accuracy: 1
time_ms: 1180
memory_kb: 34816
final_rank: 10

code_snippet: #include <iostream>
#include <iomanip>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>
// #include "Src/Utility/BinarySearch.hpp"
// #include "Src/Sequence/CompressedSequence.hpp"
// #include "Src/Sequence/RunLengthEncoding.hpp"
// using namespace zawa;
// #include "atcoder/modint"
// using mint = atcoder::modint998244353;
std::string S, T;
std::vector<std::vector<int>> next_table(const std::string& s) {
    std::vector res(2, std::vector<int>(s.size() + 1, (int)s.size()));
    int last[2]{(int)s.size(),(int)s.size()};
    for (int i = (int)s.size() - 1 ; i >= 0 ; i--) {
        last[s[i] - '0'] = i;
        res[0][i] = last[0];
        res[1][i] = last[1];
    }
    return res;
}
int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    std::cin >> S >> T;
    auto ns = next_table(S), nt = next_table(T);
    const int INF = (int)1e9;
    std::vector dp(S.size() + 2, std::vector(T.size() + 2, INF));
    struct item {
        int v{-1}, x, y;
    };
    std::vector go(S.size() + 2, std::vector<item>(T.size() + 2));
    dp[S.size() + 1][T.size() + 1] = 0;
    for (int i = (int)S.size() + 1 ; i >= 0 ; i--) for (int j = (int)T.size() + 1 ; j >= 0 ; j--) {
        for (int k = 1 ; k >= 0 ; k--) {
            int ni = i == (int)S.size() + 1 ? i : ns[k][i] + 1;
            int nj = j == (int)T.size() + 1 ? j : nt[k][j] + 1;
            if (dp[i][j] >= dp[ni][nj] + 1) {
                dp[i][j] = dp[ni][nj] + 1;
                go[i][j] = {k,ni,nj};
            }
        }
    }
    // for (int i = 0 ; i < (int)S.size() + 2 ; i++) {
    //     for (int j = 0 ; j < (int)T.size() + 2 ; j++) {
    //         auto [v, x, y] = go[i][j];
    //         std::cout << '(' << v << ',' << x << ',' << y << ')';
    //     }
    //     std::cout << '\n';
    // }
    std::string ans;
    int x = 0, y = 0;
    while (dp[0][0]--) {
        ans += go[x][y].v + '0';
        int nx = go[x][y].x, ny = go[x][y].y;
        x = nx;
        y = ny;
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 110
memory_kb: 253952
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int NN = 4000 + 4;
char A[NN], B[NN];
int N, M, PA[NN][2], PB[NN][2], D[NN][NN], F[NN][NN];
vector<int> ans;
int dp(int x, int y) {
  int &d = D[x][y];
  if (d > -1) return d;
  if (x > N and y > M) return d = 0;
  int d0 = dp(PA[x][0], PB[y][0]), d1 = dp(PA[x][1], PB[y][1]);
  return (F[x][y] = d1 < d0), d = min(d0, d1) + 1;  // 选择长度较小的为答案
}
void getans(int x, int y) {
  if (x > N and y > M) return;
  int d = F[x][y];
  ans.push_back(d), getans(PA[x][d], PB[y][d]);
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> (A + 1) >> (B + 1), N = strlen(A + 1), M = strlen(B + 1);
  memset(D, -1, sizeof(D));
  PA[N + 1][0] = PA[N + 1][1] = N + 1, PB[M + 1][0] = PB[M + 1][1] = M + 1;
  for (int i = N, i1 = i + 1; i >= 0; i--, i1--)
    PA[i][0] = PA[i1][0], PA[i][1] = PA[i1][1], PA[i][A[i1] != '0'] = i1;
  for (int i = M, i1 = i + 1; i >= 0; i--, i1--)
    PB[i][0] = PB[i1][0], PB[i][1] = PB[i1][1], PB[i][B[i1] != '0'] = i1;
  dp(0, 0), getans(0, 0);
  for (int i : ans) printf("%d", i);
  return printf("\n"), 0;
}
accuracy: 1
time_ms: 30
memory_kb: 127432
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = short;
#define ALL(a) begin(a), end(a)
#define rep(i,j,k) for(int (i)=(j);(i)<(k);(i)++)


template<class T> size_t HashCombine(const size_t seed,const T &v){
	return seed^(std::hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct std::hash<std::pair<T,S>>{
	size_t operator()(const std::pair<T,S> &keyval)const noexcept{
		return HashCombine(std::hash<T>()(keyval.first),keyval.second);
	}
};
int main(){
	string x,y;
	cin>>x>>y;
	ll a=x.size(),b=y.size();
	
	vector<ll>x0(a+2,-1);
	vector<ll>x1(a+2,-1);
	vector<ll>y0(b+2,-1);
	vector<ll>y1(b+2,-1);
	x0[a+1]=x1[a+1]=a+1;
	y0[b+1]=y1[b+1]=b+1;
	rep(i,0,a){
		if(x[i]=='0'){
			x0[i]=i+1;
		}else{
			x1[i]=i+1;
		}
	}
	rep(i,0,b){
		if(y[i]=='0'){
			y0[i]=i+1;
		}else{
			y1[i]=i+1;
		}
	}
	reverse(ALL(x0));
	reverse(ALL(x1));
	reverse(ALL(y0));
	reverse(ALL(y1));
	rep(i,0,a+1)if(x0[i+1]==-1)x0[i+1]=x0[i];
	rep(i,0,a+1)if(x1[i+1]==-1)x1[i+1]=x1[i];
	rep(i,0,b+1)if(y0[i+1]==-1)y0[i+1]=y0[i];
	rep(i,0,b+1)if(y1[i+1]==-1)y1[i+1]=y1[i];
	reverse(ALL(x0));
	reverse(ALL(x1));
	reverse(ALL(y0));
	reverse(ALL(y1));
	// vector<vector<vector<pair<ll,ll>>>>G(a+2,vector<vector<pair<ll,ll>>>(b+2));
	// vector<vector<vector<pair<pair<ll,ll>,ll>>>>Gi(a+2,vector<vector<pair<pair<ll,ll>,ll>>>(b+2));
	// map<pair<ll,ll>,ll>G;
	bool G[a+2][b+2]={0};
	unordered_map<pair<ll,ll>,pair<pair<ll,ll>,bool>>Gi;
	queue<pair<ll,ll>>Q;
	Q.push({0,0});
	G[0][0]=1;
	while(!Q.empty()){
		ll qi=Q.front().first,qj=Q.front().second;
		Q.pop();
		if(qi+qj==a+b+2)break;
		if(G[x0[qi]][y0[qj]]==0){
			G[x0[qi]][y0[qj]]=1;
			Q.push({x0[qi],y0[qj]});
			Gi[{x0[qi],y0[qj]}]={{qi,qj},0};
		}
		if(G[x1[qi]][y1[qj]]==0){
			G[x1[qi]][y1[qj]]=1;
			Q.push({x1[qi],y1[qj]});
			Gi[{x1[qi],y1[qj]}]={{qi,qj},1};
		}
	}
	string ans="";
	ll i=a+1,j=b+1;
	while(1){
		if(i+j==0)break;
		ll a=Gi[{i,j}].first.first;
		ll b=Gi[{i,j}].first.second;
		ll c=Gi[{i,j}].second;
		if(c==0){
			ans+='0';
		}else{
			ans+='1';
		}
		i=a,j=b;
	}
	// rep(i,0,a+1){
	// 	rep(j,0,b+1){
	// 		cerr<<V[i][j]<<" ";
	// 	}
	// 	cerr<<endl;
	// }
	reverse(ALL(ans));
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 2440
memory_kb: 193668
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rep2(i,l,n) for(int i=l;i<n;i++)
#define all(v) v.begin(), v.end()

int main() {
    cin.tie(0)->sync_with_stdio(0);
    string S,T;
    cin>>S>>T;
    reverse(all(S));
    reverse(all(T));
    int N=S.size(),M=T.size();
    vector n0S(N+2,0),n1S(N+2,0);
    n0S[N]=n0S[N+1]=N+1;
    n1S[N]=n1S[N+1]=N+1;
    per(i,N){
        if(S[i]=='1'){
            n0S[i]=n0S[i+1];
            n1S[i]=i+1;
        }else{
            n0S[i]=i+1;
            n1S[i]=n1S[i+1];
        }
    }
    vector n0T(M+2,0),n1T(M+2,0);
    n0T[M]=n0T[M+1]=M+1;
    n1T[M]=n1T[M+1]=M+1;
    per(i,M){
        if(T[i]=='1'){
            n0T[i]=n0T[i+1];
            n1T[i]=i+1;
        }else{
            n0T[i]=i+1;
            n1T[i]=n1T[i+1];
        }
    }

    vector dist(N+2,vector(M+2,(int)1e9));
    vector pch(N+2,vector(M+2,'3'));
    dist[0][0]=0;
    pch[0][0]='4';
    rep(i,N+2){
        rep(j,M+2){
            if(pch[i][j]=='3')continue;
            // cerr<<i<<' '<<j<<' '<<pch[i][j]<<endl;
            {
                // 0
                int i2=n0S[i],j2=n0T[j];
                if(dist[i2][j2]>dist[i][j]+1||(dist[i2][j2]==dist[i][j]+1&&pch[i2][j2]>'0')){
                    dist[i2][j2]=dist[i][j]+1;
                    pch[i2][j2]='0';
                }
            }
            {
                // 1
                int i2=n1S[i],j2=n1T[j];
                if(dist[i2][j2]>dist[i][j]+1||(dist[i2][j2]==dist[i][j]+1&&pch[i2][j2]>'1')){
                    dist[i2][j2]=dist[i][j]+1;
                    pch[i2][j2]='1';
                }
            }
        }
    }
    rep(i,N+2){
        per(j,M+1){
            if(dist[i][j+1]<dist[i][j]){
                dist[i][j]=dist[i][j+1];
                pch[i][j]=pch[i][j+1];
            }else if(dist[i][j+1]==dist[i][j]&&pch[i][j+1]<pch[i][j]){
                pch[i][j]=pch[i][j+1];
            }
        }
    }
    rep(j,M+2){
        per(i,N+1){
            if(dist[i+1][j]<dist[i][j]){
                dist[i][j]=dist[i+1][j];
                pch[i][j]=pch[i+1][j];
            }else if(dist[i+1][j]==dist[i][j]&&pch[i+1][j]<pch[i][j]){
                pch[i][j]=pch[i+1][j];
            }
        }
    }
    // rep(i,N+2){
    //     rep(j,M+2)cerr<<dist[i][j]<<' ';
    //     cerr<<endl;
    // }
    // cerr<<endl;
    // rep(i,N+2){
    //     rep(j,M+2)cerr<<pch[i][j]<<' ';
    //     cerr<<endl;
    // }
    string ans="";
    int len=dist[N+1][M+1];
    // cerr<<len<<endl;
    int x=N+1,y=M+1;
    per(d,len){
        // cerr<<x<<' '<<y<<endl;
        ans+=pch[x][y];
        // int x2=x,y2=y;
        if(pch[x][y]=='0'){
            x=max(0,x-1);
            while(x>0&&S[x-1]!='0'){
                x--;
            }
            y=max(0,y-1);
            while(y>0&&T[y-1]!='0'){
                y--;
            }
        }else{
            x=max(0,x-1);
            while(x>0&&S[x-1]!='1'){
                x--;
            }
            y=max(0,y-1);
            while(y>0&&T[y-1]!='1'){
                y--;
            }
        }
    }
    cout<<ans<<'\n';
}
accuracy: 1
time_ms: 260
memory_kb: 81592
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rep2(i,l,n) for(int i=l;i<n;i++)
#define all(v) v.begin(), v.end()

int main() {
    cin.tie(0)->sync_with_stdio(0);
    string S,T;
    cin>>S>>T;
    reverse(all(S));
    reverse(all(T));
    int N=S.size(),M=T.size();
    vector n0S(N+2,0),n1S(N+2,0);
    n0S[N]=n0S[N+1]=N+1;
    n1S[N]=n1S[N+1]=N+1;
    per(i,N){
        if(S[i]=='1'){
            n0S[i]=n0S[i+1];
            n1S[i]=i+1;
        }else{
            n0S[i]=i+1;
            n1S[i]=n1S[i+1];
        }
    }
    vector n0T(M+2,0),n1T(M+2,0);
    n0T[M]=n0T[M+1]=M+1;
    n1T[M]=n1T[M+1]=M+1;
    per(i,M){
        if(T[i]=='1'){
            n0T[i]=n0T[i+1];
            n1T[i]=i+1;
        }else{
            n0T[i]=i+1;
            n1T[i]=n1T[i+1];
        }
    }

    vector dist(N+2,vector(M+2,(int)1e9));
    vector pch(N+2,vector(M+2,'3'));
    dist[0][0]=0;
    pch[0][0]='4';
    rep(i,N+2){
        rep(j,M+2){
            if(pch[i][j]=='3')continue;
            // cerr<<i<<' '<<j<<' '<<pch[i][j]<<endl;
            {
                // 0
                int i2=n0S[i],j2=n0T[j];
                if(dist[i2][j2]>dist[i][j]+1||(dist[i2][j2]==dist[i][j]+1&&pch[i2][j2]>'0')){
                    dist[i2][j2]=dist[i][j]+1;
                    pch[i2][j2]='0';
                }
            }
            {
                // 1
                int i2=n1S[i],j2=n1T[j];
                if(dist[i2][j2]>dist[i][j]+1||(dist[i2][j2]==dist[i][j]+1&&pch[i2][j2]>'1')){
                    dist[i2][j2]=dist[i][j]+1;
                    pch[i2][j2]='1';
                }
            }
        }
    }
    rep(i,N+2){
        per(j,M+1){
            if(dist[i][j+1]<dist[i][j]){
                dist[i][j]=dist[i][j+1];
                pch[i][j]=pch[i][j+1];
            }else if(dist[i][j+1]==dist[i][j]&&pch[i][j+1]<pch[i][j]){
                pch[i][j]=pch[i][j+1];
            }
        }
    }
    rep(j,M+2){
        per(i,N+1){
            if(dist[i+1][j]<dist[i][j]){
                dist[i][j]=dist[i+1][j];
                pch[i][j]=pch[i+1][j];
            }else if(dist[i+1][j]==dist[i][j]&&pch[i+1][j]<pch[i][j]){
                pch[i][j]=pch[i+1][j];
            }
        }
    }
    // rep(i,N+2){
    //     rep(j,M+2)cerr<<dist[i][j]<<' ';
    //     cerr<<endl;
    // }
    // cerr<<endl;
    // rep(i,N+2){
    //     rep(j,M+2)cerr<<pch[i][j]<<' ';
    //     cerr<<endl;
    // }
    string ans="";
    int len=dist[N+1][M+1];
    // cerr<<len<<endl;
    int x=N+1,y=M+1;
    per(d,len){
        // cerr<<x<<' '<<y<<endl;
        ans+=pch[x][y];
        // int x2=x,y2=y;
        if(pch[x][y]=='0'){
            --x;
            while(x>0&&S[x-1]!='0'){
                x--;
            }
            --y;
            while(y>0&&T[y-1]!='0'){
                y--;
            }
        }else{
            --x;
            while(x>0&&S[x-1]!='1'){
                x--;
            }
            --y;
            while(y>0&&T[y-1]!='1'){
                y--;
            }
        }
    }
    cout<<ans<<'\n';
}
accuracy: 0.1346153846153846
time_ms: 250
memory_kb: 81564
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define rep(i,s,n) for (int i = (int)(s); i < (int)(n); i++)
#define all(v) begin(v),end(v)
using namespace std;
using ll = long long;
bool chmin(auto &a, auto b){ return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b){ return a < b ? a = b, 1 : 0; }

int main() {
    cin.tie(0)->sync_with_stdio(0);
    string s; cin >> s;
    string t; cin >> t;
    int n = s.size();
    int m = t.size();
    vector nxts(2, vector<int>(n+2,n+1));
    vector nxtt(2, vector<int>(m+2,m+1));
    rep(i,0,n) {
        if (s[i] == '0') {
            chmin(nxts[0][i], i+1);
        }else {
            chmin(nxts[1][i], i+1);
        }
    }
    rep(i,0,m) {
        if (t[i] == '0') {
            chmin(nxtt[0][i], i+1);
        }else {
            chmin(nxtt[1][i], i+1);
        }
    }
    for (int i=n-1; i>=0; i--) {
        rep(j,0,2) {
            chmin(nxts[j][i], nxts[j][i+1]);
        }
    }
    for (int i=m-1; i>=0; i--) {
        rep(j,0,2) {
            chmin(nxtt[j][i], nxtt[j][i+1]);
        }
    }

    vector seen(n+2, vector<bool>(m+2, false));
    vector dp(n+2, vector<int>(m+2, 1e9));

    dp[n+1][m+1] = 0;
    seen[n+1][m+1] = true;

    auto calc = [&](auto self, int i, int j) -> int {
        if (i == n+1 && j == m+1) return 0;
        if (seen[i][j]) return dp[i][j];
        int ret = 1e9;
        rep(x,0,2) {
            int ni = nxts[x][i];
            int nj = nxtt[x][j];
            chmin(ret, self(self, ni, nj) + 1);
        }
        seen[i][j] = 1;
        dp[i][j] = ret;
        return ret;
    };

    int i = 0;
    int j = 0;
    vector<int> ans;
    while (i < n+1 || j < m+1) {
        bool mode = 0;
        rep(x,0,2) {
            int ni = nxts[x][i];
            int nj = nxtt[x][j];
            if (calc(calc, i, j) - 1 == calc(calc, ni, nj)) {
                ans.push_back(x);
                i = ni;
                j = nj;
                mode = 1;
                break;
            }
        }
        assert(mode);
    }

    assert((int)ans.size() == calc(calc, 0, 0));
    for (int x: ans) {
        cout << x;
    }
    cout << '\n';

}
accuracy: 1
time_ms: 80
memory_kb: 68608
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;

const int inf = 1 << 30;
void chmin(int &a, int b) { a = min(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    string s,t ;
    cin >> s >> t;
    int n = s.size();
    int m = t.size();
    vector dp(n + 2, vector(m + 2, inf));
    dp[n + 1][m + 1] = 0;
    vector nxs(n + 2, vector(2, n + 1));
    for(int i = n - 1; i >= 0; i --) {
        nxs[i] = nxs[i + 1];
        nxs[i][s[i] - '0'] = i + 1;
    }
    vector nxt(m + 2, vector(2, m + 1));
    for(int i = m - 1; i >= 0; i --) {
        nxt[i] = nxt[i + 1];
        nxt[i][t[i] - '0'] = i + 1;
    }
    vector p(n + 2, vector(m + 2, -1));
    vector ch(n + 2, vector(m + 2, true));
    for(int i = n + 1; i >= 0; i --) {
        for(int j = m + 1; j >= 0; j --) {
            rep(k, 2) {
                int ns = nxs[i][k];
                int nt = nxt[j][k];
                if(dp[i][j] > dp[ns][nt] + 1) {
                    dp[i][j] = dp[ns][nt] + 1;
                    p[i][j] = ns * 10000 + nt;
                    ch[i][j] = k; 
                }
            }
        }
    }
    int nowy = 0, nowx = 0;
    string ans = "";
    while(p[nowy][nowx] != -1) {
        ans += (ch[nowy][nowx] ? "1" : "0");
        int P = p[nowy][nowx];
        int y = P / 10000;
        int x = P % 10000;
        nowy = y;
        nowx = x;
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 131216
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define ALL(v) v.begin(),v.end()
#define dbg(x) cerr << #x << ": " << x << endl;

int main() {
    string s,t;
    cin >> s >> t;

    // sv[i][j] = j番目の文字より後ろの最小のi
    vector<vector<int>> sv(2,vector<int>(s.size()+2, s.size()+1));
    vector<vector<int>> tv(2,vector<int>(t.size()+2, t.size()+1));

    for (int j = 0; j < s.size(); ++j) {
        sv[s[j]-'0'][0] = min(sv[s[j]-'0'][0], j+1);
    }
    for (int i = 0; i < s.size(); ++i) {
        for (int j = i+1; j < s.size(); ++j) {
            sv[s[j]-'0'][i+1] = min(sv[s[j]-'0'][i+1], j+1);
        }
    }
    for (int j = 0; j < t.size(); ++j) {
        tv[t[j]-'0'][0] = min(tv[t[j]-'0'][0], j+1);
    }
    for (int i = 0; i < t.size(); ++i) {
        for (int j = i+1; j < t.size(); ++j) {
            tv[t[j]-'0'][i+1] = min(tv[t[j]-'0'][i+1], j+1);
        }
    }
    

    vector<vector<int>> dp(s.size()+2, vector<int>(t.size()+2, INT_MAX));
    int offset = 1e5;
    dp[0][0] = 0;
    for (int i = 0; i <= s.size()+1; ++i) {
        for (int j = 0; j <= t.size()+1; ++j) {
            if (dp[i][j] == INT_MAX) continue;
            for (int k = 0; k < 2; ++k) {
                int ni = sv[k][i];
                int nj = tv[k][j];
                dp[ni][nj] = min(dp[ni][nj], dp[i][j]+1);
            }
        }
    }

    vector<vector<int>> used(s.size()+2, vector<int>(t.size()+2, 0));
    used[s.size()+1][t.size()+1] = 3;
    for (int i = s.size()+1; i >= 0; --i) {
        for (int j = t.size()+1; j >= 0; --j) {
            for (int k = 0; k < 2; ++k) {
                int ni = sv[k][i];
                int nj = tv[k][j];
                if (used[ni][nj] > 0 && dp[i][j]+1 == dp[ni][nj]) used[i][j] |= 1<<k;
            }
        }
    }

    // dbg(dp[s.size()+1][t.size()+1])
    string ans;
    int tmp_i = 0;
    int tmp_j = 0;
    while (tmp_i < s.size()+1 || tmp_j < t.size()+1) {
        if (used[tmp_i][tmp_j]&1) {
            ans.push_back('0');
            tmp_i = sv[0][tmp_i];
            tmp_j = tv[0][tmp_j];
        }
        else {
            ans.push_back('1');
            tmp_i = sv[1][tmp_i];
            tmp_j = tv[1][tmp_j];
        }
        // assert(used[tmp_i][tmp_j] > 0);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 128480
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    string S, T;
    cin >> S >> T;
    S = S + '$', T = T + '$';
    int N = S.size(), M = T.size();
    vector<vector<int>> A(N+1,vector<int>(2));
    vector<vector<int>> B(M+1,vector<int>(2));
    int Cur[2] = {N,N};
    A[N][0] = A[N][1] = N;
    rrep(i,0,N) {
        if (S[i] == '0') Cur[0] = i+1;
        if (S[i] == '1') Cur[1] = i+1;
        rep(j,0,2) A[i][j] = Cur[j];
    }
    Cur[0] = Cur[1] = M;
    B[M][0] = B[M][1] = M;
    rrep(i,0,M) {
        if (T[i] == '0') Cur[0] = i+1;
        if (T[i] == '1') Cur[1] = i+1;
        rep(j,0,2) B[i][j] = Cur[j];
    }
    vector<vector<int>> DP(N+1,vector<int>(M+1,inf));
    vector Next(N+1,vector<tuple<int,int,int>>(M+1));
    DP[N][M] = 0;
    rrep(i,0,N+1) {
        rrep(j,0,M+1) {
            rep(k,0,2) {
                if (chmin(DP[i][j],DP[A[i][k]][B[j][k]]+1)) {
                    Next[i][j] = {k,A[i][k],B[j][k]};
                }
            }
        }
    }
    int CurX = 0, CurY = 0;
    string ANS = "";
    while(1) {
        if (CurX == N && CurY == M) break;
        auto [NC, NX, NY] = Next[CurX][CurY];
        ANS += (char)(NC+'0');
        CurX = NX, CurY = NY;
    }
    cout << ANS << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 254052
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}


void solve() {
  string S, T; cin >> S >> T;
  S += '*', T += '*';
  int s = S.length(), t = T.length();
  
  vector<array<int, 2>> nexS(s+1), nexT(t+1);
  {
    int s0 = s, s1 = s;
    for (int i = s; i >= 0; --i) {
      nexS[i] = {s0, s1};
      
      if (i == 0) continue;
      if (S[i-1] == '0') s0 = i;
      if (S[i-1] == '1') s1 = i;
    }
    
    int t0 = t, t1 = t;
    for (int i = t; i >= 0; --i) {
      nexT[i] = {t0, t1};
      
      if (i == 0) continue;
      if (T[i-1] == '0') t0 = i;
      if (T[i-1] == '1') t1 = i;
    }
  }
  
  const int INF = 1e9;
  
  vector dist2(s+1, vector<int>(t+1, INF));
  dist2[s][t] = 0;
  for (int x = s; x >= 0; --x) {
    for (int y = t; y >= 0; --y) {
      auto [s0, s1] = nexS[x];
      auto [t0, t1] = nexT[y];
      
      chmin(dist2[x][y], dist2[s0][t0] + 1);
      chmin(dist2[x][y], dist2[s1][t1] + 1);
    }
  }
  // cout << dist2[0][0] << endl;
  
  string ans = "";
  {
    ll x = 0, y = 0;
    while (x < s || y < t) {
      auto [s0, s1] = nexS[x];
      auto [t0, t1] = nexT[y];
      ll d = dist2[x][y];
      ll d0 = dist2[s0][t0];
      ll d1 = dist2[s1][t1];
      
      if (d0 < d) ans += '0', x = s0, y = t0;
      else ans += '1', x = s1, y = t1;
    }
  }
  cout << ans << endl;
  
  return;
}

int main() {
  solve();
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 66176
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <climits> // INT_MAX

using namespace std;

// 次に登場する各文字のインデックスを計算する関数
// res[i][c] は i 文字目以降で最初に文字 c が登場するインデックス（存在しない場合は文字列の長さ）
vector<vector<int>> computeNextIndices(const string &str) {
    int length = str.size();
    vector<vector<int>> nextIndices(length + 1, vector<int>(2, length));
    
    // 文字列を逆から走査して次に登場する文字の位置を記録する
    for (int i = length - 1; i >= 0; --i) {
        for (int c = 0; c < 2; ++c) {
            nextIndices[i][c] = nextIndices[i + 1][c];
        }
        nextIndices[i][str[i] - '0'] = i;
    }
    
    return nextIndices;
}

int main() {
    // 入力文字列を受け取る
    string S, T;
    cin >> S >> T;
    
    // 各文字列の次に出現するインデックスを計算する
    auto nextS = computeNextIndices(S);
    auto nextT = computeNextIndices(T);
    
    int n = S.size();
    int m = T.size();
    
    // DP テーブルの初期化
    // dp[i][j] は、i 文字目以降と j 文字目以降で最短の非部分列を見つけるコスト
    vector<vector<int>> dp(n + 2, vector<int>(m + 2, INT_MAX));
    
    // 部分列を復元するためのテーブル
    vector<vector<pair<char, pair<int, int>>>> reconstruction(n + 2, vector<pair<char, pair<int, int>>>(m + 2, {'0', {n, m}}));
    
    // 初期条件
    dp[n][m] = 1;
    dp[n + 1][m + 1] = 0;
    
    // DP テーブルを埋める
    for (int i = n + 1; i >= 0; --i) {
        for (int j = m + 1; j >= 0; --j) {
            if (i == n + 1 && j == m + 1) continue;
            
            for (int c = 0; c < 2; ++c) {
                int nextI = (i >= n) ? n : nextS[i][c];
                int nextJ = (j >= m) ? m : nextT[j][c];
                
                // dp テーブルの値を更新する
                if (dp[i][j] > dp[nextI + 1][nextJ + 1] + 1) {
                    dp[i][j] = dp[nextI + 1][nextJ + 1] + 1;
                    reconstruction[i][j] = {char('0' + c), {nextI + 1, nextJ + 1}};
                }
            }
        }
    }
    
    // 最短共通非部分列を復元する
    string result = "";
    int i = 0, j = 0;
    for (int k = 0; k < dp[0][0]; ++k) {
        auto p = reconstruction[i][j];
        result += p.first;
        i = p.second.first;
        j = p.second.second;
    }
    
    // 結果を出力
    cout << result << endl;
    
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 254108
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = int;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    vector<string> S(2);
    cin>>S[0]>>S[1];
    // reverse(S[0].begin(),S[0].end());
    // reverse(S[1].begin(),S[1].end());
    vector<vector<vector<ll>>> idx(2,vector<vector<ll>>(2));
    vector<ll> L(2);
    L[0]=S[0].size();
    L[1]=S[1].size();
    for(int i=0;i<2;i++)for(int j=0;j<L[i];j++)idx[i][S[i][j]-'0'].push_back(j);
        
    vector<vector<tuple<ll,ll,ll,ll>>> DP(L[0]+2,vector<tuple<ll,ll,ll,ll>>(L[1]+2,{1e18,-1,-1,-1}));
    DP[0][0]={0,-1,-1,-1};
    queue<pair<ll,ll>> Q;
    Q.push({0,0});
    while(!Q.empty()){
        int i=Q.front().first;
        int j=Q.front().second;
        Q.pop();
        if(i==L[0]+1&&j==L[1]+1)continue;
        for(int k=0;k<2;k++){
            auto p=lower_bound(idx[0][k].begin(),idx[0][k].end(),i);
            int ni=L[0]+1;
            if(p!=idx[0][k].end())ni=(*p)+1;
            auto q=lower_bound(idx[1][k].begin(),idx[1][k].end(),j);
            int nj=L[1]+1;
            if(q!=idx[1][k].end())nj=(*q)+1;
            if(get<0>(DP[ni][nj]) > get<0>(DP[i][j])+1){
                DP[ni][nj]=min(DP[ni][nj],{get<0>(DP[i][j])+1,k,i,j});
                Q.push({ni,nj});
            }
        }
    }
    string AN="";
    ll x=L[0]+1,y=L[1]+1;
    while(x>0){
        AN.push_back(get<1>(DP[x][y])+'0');
        ll nx=get<2>(DP[x][y]);
        ll ny=get<3>(DP[x][y]);
        x=nx;
        y=ny;
    }
    reverse(AN.begin(),AN.end());
    cout<<AN<<endl;
    
}
accuracy: 1
time_ms: 540
memory_kb: 253556
final_rank: 18

code_snippet: #define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <cmath>
#include<sstream>
#include<list>
#include<iomanip>
#include <cstdlib>
#include <cstring>
#include <stack>
#include <bitset>
#include <cassert>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
const int INF = 1000000007;
const long long LINF = 1e18 + 7;
const int MAX_N = 1200010;
const int MAX_W = 600010;
const int MAX_ARRAYK = 100000;
double PI = 3.14159265358979323846;
//using ll = long long; 


// https://drken1215.hatenablog.com/entry/2018/12/19/111700

using pint = pair<int, int>;

long long mod = 1000000007;

vector<vector<int> > calcNext(string S) {
    int n = S.size();
    vector<vector<int> > res(n + 1, vector<int>(2, n));

    for (int i = n - 1; i >= 0; i--) {
        for (int j = 0; j < 2; j++) {
            res[i][j] = res[i + 1][j];
        }
        res[i][S[i] - '0'] = i;
    }

    return res;
}

string solve(string S, string T) {
    
    vector<vector<int> > nextS = calcNext(S);
    vector<vector<int> > nextT = calcNext(T);

    int N = S.size();
    int M = T.size();

    vector<vector<int> > dp(N + 2, vector<int>(M + 2, INF));
    vector<vector<pair<char, pint> > > recon(N + 2, vector<pair<char, pint> >(M + 2, { '0', pint(N, M) }));

    dp[N][M] = 1;
    dp[N + 1][M + 1] = 0;

    for (int i = N + 1; i >= 0; i--) {
        for (int j = M + 1; j >= 0; j--) {
            if (i == N + 1 && j == M + 1) continue;
            for (int k = 0; k < 2; k++) {
                int ni, nj;
                if (i >= N) {
                    ni = N;
                }
                else {
                    ni = nextS[i][k];
                }

                if (j >= M) {
                    nj = M;
                }
                else {
                    nj = nextT[j][k];
                }

                if (dp[i][j] > dp[ni + 1][nj + 1] + 1) {
                    dp[i][j] = dp[ni + 1][nj + 1] + 1;
                    recon[i][j] = { '0' + k, pint(ni + 1, nj + 1) };
                }
            }
        }
    }

    // 復元
    string res = "";
    int i = 0;
    int j = 0;

    for (int k = 0; k < dp[0][0]; k++) {
        pair<char, pint> p = recon[i][j];
        res += p.first;
        i = p.second.first;
        j = p.second.second;
    }

    return res;

}


int main() {

    string S, T;
    cin >> S >> T;

    cout << solve(S, T) << endl;

    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 254076
final_rank: 17