Problem:
Score : 2400 points

Problem Statement

Takahashi and Aoki love calculating things, so they will play with numbers now.

First, they came up with one positive integer each. Takahashi came up with X, and Aoki came up with Y.
Then, they will enjoy themselves by repeating the following operation K times:

Compute the bitwise AND of the number currently kept by Takahashi and the number currently kept by Aoki. Let Z be the result.

Then, add Z to both of the numbers kept by Takahashi and Aoki.

However, it turns out that even for the two math maniacs this is just too much work.
Could you find the number that would be kept by Takahashi and the one that would be kept by Aoki eventually?

Note that input and output are done in binary.
Especially, X and Y are given as strings S and T of length N and M consisting of 0 and 1, respectively, whose initial characters are guaranteed to be 1.

Constraints

1 ≤ K ≤ 10^6

1 ≤ N,M ≤ 10^6

The initial characters of S and T are 1.

Input

Input is given from Standard Input in the following format:

N M K
S
T

Output

In the first line, print the number that would be kept by Takahashi eventually; in the second line, print the number that would be kept by Aoki eventually.
Those numbers should be represented in binary and printed as strings consisting of 0 and 1 that begin with 1.

Sample Input 1

2 3 3
11
101

Sample Output 1

10000
10010

The values of X and Y after each operation are as follows:

After the first operation: (X,Y)=(4,6).

After the second operation: (X,Y)=(8,10).

After the third operation: (X,Y)=(16,18).

Sample Input 2

5 8 3
10101
10101001

Sample Output 2

100000
10110100

Sample Input 3

10 10 10
1100110011
1011001101

Sample Output 3

10000100000010001000
10000100000000100010

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.max;
import static java.lang.System.exit;
import static java.util.Arrays.fill;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

	static class Token implements Comparable<Token> {
		int index;
		final int time;

		Token(int index, int time) {
			this.index = index;
			this.time = time;
		}

		public int compareTo(Token o) {
			return time - o.time;
		}
	}

	static void solve() throws Exception {
		int c1 = scanInt();
		int c2 = scanInt();
		int c = max(c1, c2);
		int k = scanInt();
		int bit[] = new int[c];
		String s1 = scanString();
		for (int i = 0; i < c1; i++) {
			if (s1.charAt(i) == '1') {
				bit[c1 - i - 1] |= 1;
			}
		}
		String s2 = scanString();
		for (int i = 0; i < c2; i++) {
			if (s2.charAt(i) == '1') {
				bit[c2 - i - 1] |= 2;
			}
		}
		int lCap = 2 * c + 2;
		int lIndex[] = new int[lCap], lValue[] = new int[lCap];
		int lPrev[] = new int[lCap], lNext[] = new int[lCap], lFree = 1;
		Token lToken[] = new Token[lCap];
		for (int i = 1; i < lCap - 1; i++) {
			lNext[i] = i + 1;
		}
		lNext[lCap - 1] = -1;
		lPrev[0] = lNext[0] = 0;
		lIndex[0] = lValue[0] = -1;
		PriorityQueue<Token> pq = new PriorityQueue<>();
		for (int i = 0; i < c; i++) {
			if (bit[i] == 0) {
				continue;
			}
			int cur = lFree;
			lFree = lNext[lFree];
			lIndex[cur] = i;
			lValue[cur] = bit[i];
			int last = lPrev[0];
			if (lValue[last] == 3 && lValue[cur] != 3) {
				lToken[last] = new Token(last, lIndex[cur] - lIndex[last]);
				pq.add(lToken[last]);
			}
			lPrev[cur] = last;
			lNext[cur] = 0;
			lPrev[0] = lNext[last] = cur;
		}
		for (int step = 1; step <= k; step++) {
			while (!pq.isEmpty() && pq.element().time == step) {
				int cur = pq.remove().index;
				lToken[cur] = null;
				int v;
				{
					int next = lNext[cur];
					v = lValue[next];
					lValue[cur] = 3 ^ v;
					lIndex[cur] += step;
					int prev = lPrev[cur];
					if (lValue[prev] == 3) {
						lToken[prev] = new Token(prev, lIndex[cur] - lIndex[prev]);
						pq.add(lToken[prev]);
					}
					int next2 = lNext[next];
					lNext[cur] = next2;
					lPrev[next2] = cur;
					lNext[next] = lFree;
					lFree = next;
				}
				int curIndex = lIndex[cur];
				while (true) {
					int next = lNext[cur];
					++curIndex;
					if (lValue[next] != 3 && lIndex[next] == curIndex) {
						if (lValue[next] == v) {
							int next2 = lNext[next];
							lNext[cur] = next2;
							lPrev[next2] = cur;
							lNext[next] = lFree;
							lFree = next;
						} else {
							lValue[next] = 3;
							lIndex[next] -= step;
							int next2 = lNext[next];
							if (next2 != 0 && lValue[next2] != 3) {
								lToken[next] = new Token(next, lIndex[next2] - lIndex[next]);
								pq.add(lToken[next]);
							}
							break;
						}
					} else {
						int neww = lFree;
						lFree = lNext[lFree];
						lIndex[neww] = curIndex;
						lValue[neww] = v;
						lPrev[neww] = cur;
						lNext[neww] = next;
						lPrev[next] = lNext[cur] = neww;
						break;
					}
				}
			}
		}
		int last = lPrev[0];
		int maxIndex = lValue[last] == 3 ? lIndex[last] + k : lIndex[last];
		char bits0[] = new char[maxIndex + 1], bits1[] = new char[maxIndex + 1];
		fill(bits0, '0');
		fill(bits1, '0');
		int firstBit0 = -1, firstBit1 = -1;
		for (int cur = lNext[0]; cur != 0; cur = lNext[cur]) {
			int curValue = lValue[cur];
			int curIndex = curValue == 3 ? lIndex[cur] + k : lIndex[cur];
			if ((curValue & 1) != 0) {
				bits0[maxIndex - curIndex] = '1';
				firstBit0 = maxIndex - curIndex;
			}
			if ((curValue & 2) != 0) {
				bits1[maxIndex - curIndex] = '1';
				firstBit1 = maxIndex - curIndex;
			}
		}
		out.println(new String(bits0, firstBit0, maxIndex - firstBit0 + 1));
		out.print(new String(bits1, firstBit1, maxIndex - firstBit1 + 1));
	}

	static int scanInt() throws IOException {
		return parseInt(scanString());
	}

	static long scanLong() throws IOException {
		return parseLong(scanString());
	}

	static String scanString() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}