Problem:
A: 情報検索 / Information Search

問題

ポスティングリストとは、検索語と出現文書 ID の対応関係を持たせたリストである。例えば

北海道: 1, 2, 4, 9

観光: 1, 3, 4, 7

などである。

上記のポスティングリストから、and 検索をすると、ID 1, 4 の文書がヒットし、or 検索をすると、ID 1, 2, 3, 4, 7, 9 がヒットする。

ここで and 検索とは「どちらのリストにも含まれる要素を列挙する」ことであり、 or 検索とは「少なくともどちらか一方のリストに含まれる要素を列挙する」ことである。

ポスティングリストが与えられるので、and 検索と or 検索の結果をそれぞれ出力せよ。

入力形式

n m
a_1 a_2 $\ldots$ a_n
b_1 b_2 $\ldots$ b_m

入力はすべて整数からなる。

1 行目には検索すべき 2 つのポスティングリストの長さ n と m が空白区切りで与えられる。

2 行目と 3 行目にはそれぞれのポスティングリストに含まれる ID が空白区切りで与えられる。

制約

1 \leq n, m \leq 2\times10^5

a_i < a_j (i < j)

b_i < b_j (i < j)

1 \leq a_i, b_i \leq 10^9

出力形式

and 検索のヒット数を A、or 検索のヒット数を B とする。

最初の一行に A B の順に空白区切りで出力せよ。

続く A 行に and 検索でヒットした ID を昇順に出力せよ。

続く B 行に or 検索でヒットした ID を昇順に出力せよ。

入力例1

4 4
1 2 4 9
1 3 4 7

出力例1

2 6
1
4
1
2
3
4
7
9

入力例2

4 4
1 3 5 7
2 4 6 8

出力例2

0 8
1
2
3
4
5
6
7
8

入力例3

3 5
1 2 3
1 2 3 4 5

出力例3

3 5
1
2
3
1
2
3
4
5

Solution in C# (judge verdict: Accepted)

using System.Collections.Generic;
using System.Linq;
using System;

public class hello
{
	public static void Main()
	{
		string[] line = Console.ReadLine().Trim().Split(' ');
		var n = int.Parse(line[0]);
		var m = int.Parse(line[1]);
		line = Console.ReadLine().Trim().Split(' ');
		var a = Array.ConvertAll(line, int.Parse);
		line = Console.ReadLine().Trim().Split(' ');
		var b = Array.ConvertAll(line, int.Parse);
		var pand = new List<int>();
		var por = new List<int>();
		getList(pand, por, a, b, n, m);
		Console.WriteLine("{0} {1}", pand.Count(), por.Count());
		if (pand.Count() > 0) Console.WriteLine(string.Join("\n", pand));
		if (por.Count() > 0) Console.WriteLine(string.Join("\n", por));
	}
	static void getList(List<int> pand, List<int> por, int[] a, int[] b, int n, int m)
	{
		var pa = 0; var pb = 0;
		while (true)
		{
			if (a[pa] == b[pb])
			{
				pand.Add(a[pa]);
				por.Add(a[pa]);
				pa++;
				pb++;
			}
			else if (a[pa] > b[pb])
			{
				por.Add(b[pb]);
				pb++;
			}
			else
			{
				por.Add(a[pa]);
				pa++;
			}
			if (pa == n)
			{
				while (pb < m) { por.Add(b[pb]); pb++; }
				break;
			}
			if (pb == m)
			{
				while (pa < n) { por.Add(a[pa]); pa++; }
				break;
			}
		}
	}
}