Hidden Bipartite Graph
Contest: Lyft Level 5 Challenge 2018 - Elimination Round
Difficulty rating: 2800
Tags: binary search, constructive algorithms, dfs and similar, graphs, interactive

Bob has a simple undirected connected graph (without self-loops and multiple edges). He wants to learn whether his graph is bipartite (that is, you can paint all vertices of the graph into two colors so that there is no edge connecting two vertices of the same color) or not. As he is not very good at programming, he asked Alice for help. He does not want to disclose his graph to Alice, but he agreed that Alice can ask him some questions about the graph.

The only question that Alice can ask is the following: she sends $$$s$$$ — a subset of vertices of the original graph. Bob answers with the number of edges that have both endpoints in $$$s$$$. Since he doesn't want Alice to learn too much about the graph, he allows her to ask no more than $$$20000$$$ questions. Furthermore, he suspects that Alice might introduce false messages to their communication channel, so when Alice finally tells him whether the graph is bipartite or not, she also needs to provide a proof — either the partitions themselves or a cycle of odd length.

Your task is to help Alice to construct the queries, find whether the graph is bipartite.

Input format:
The first line contains a single integer $$$n$$$ ($$$1 \leq n \leq 600$$$) — the number of vertices in Bob's graph.

Interaction format:
First, read an integer $$$n$$$ ($$$1\leq n\leq 600$$$) — the number of vertices in Bob's graph.

To make a query, print two lines. First of which should be in the format "? k" ($$$1 \leq k \leq n$$$), where $$$k$$$ is the size of the set to be queried. The second line should contain $$$k$$$ space separated distinct integers $$$s_1, s_2, \dots, s_k$$$ ($$$1 \leq s_i \leq n$$$) — the vertices of the queried set.

After each query read a single integer $$$m$$$ ($$$0 \leq m \leq \frac{n(n-1)}{2}$$$) — the number of edges between the vertices of the set $$$\{s_i\}$$$.

You are not allowed to ask more than $$$20000$$$ queries.

If $$$m = -1$$$, it means that you asked more queries than allowed, or asked an invalid query. Your program should immediately terminate (for example, by calling exit(0)). You will receive Wrong Answer; it means that you asked more queries than allowed, or asked an invalid query. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.

After printing a query do not forget to print end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

- fflush(stdout) or cout.flush() in C++;
- System.out.flush() in Java;
- flush(output) in Pascal;
- stdout.flush() in Python;
- see documentation for other languages.

When you know the answer, you need to print it.

The format of the answer depends on whether the graph is bipartite or not.

If the graph is bipartite, print two lines. The first should contain the letter "Y" (short for "YES") followed by a space, and then a single integer $$$s$$$ ($$$0 \leq s \leq n$$$) — the number of vertices in one of the partitions. Second line should contain $$$s$$$ integers $$$a_1, a_2, \dots, a_s$$$ — vertices belonging to the first partition. All $$$a_i$$$ must be distinct, and all edges in the main graph must have exactly one endpoint in the set $$$\{a_i\}$$$.

If the graph is not bipartite, print two lines. The first should contain the letter "N" (short for "NO") followed by a space, and then a single integer $$$l$$$ ($$$3 \leq l \leq n$$$) — the length of one simple cycle of odd length. Second line should contain $$$l$$$ integers $$$c_1, c_2, \dots, c_l$$$ — the vertices along the cycle. It must hold that for all $$$1 \leq i \leq l$$$, there is an edge $$$\{c_i, c_{(i \mod l)+1}\}$$$ in the main graph, and all $$$c_i$$$ are distinct.

If there are multiple possible answers, you may print any of them.

Hacks format For hacks, use the following format:

The first line contains two integers $$$n$$$ and $$$m~(1 \leq n \leq 600, 0 \leq m \leq \frac{n(n-1)}{2})$$$ — the number of vertices and edges of the graph, respectively.

Each of the next $$$m$$$ lines contains two integers $$$u_i$$$ and $$$v_i~(1 \leq u_i, v_i \leq n)$$$ mean that there is an edge between $$$u_i$$$ and $$$v_i$$$. There must not be any multiple edges, no loops, and the graph must be connected.

For example, you need to use this test to get the first sample:

Constraints:
Time limit: 4.0 s
Memory limit: 256.0 MB

Note:
In the first case, Alice learns that there are $$$4$$$ edges in the whole graph. Over the course of the next three queries, she learns that vertex $$$1$$$ has two neighbors: $$$3$$$ and $$$4$$$. She then learns that while vertex $$$2$$$ is adjacent to $$$4$$$, the vertex $$$3$$$ isn't adjacent to $$$4$$$. There is only one option for the remaining edge, and that is $$$(2, 3)$$$. This means that the graph is a cycle on four vertices, with $$$(1, 2)$$$ being one partition and $$$(3, 4)$$$ being the second. Here, it would be also valid to output "3 4" on the second line.

In the second case, we also have a graph on four vertices and four edges. In the second query, Alice learns that there are three edges among vertices $$$(1, 2, 4)$$$. The only way this could possibly happen is that those form a triangle. As the triangle is not bipartite, Alice can report it as a proof. Notice that she does not learn where the fourth edge is, but she is able to answer Bob correctly anyway.

Example input:
4
4
0
1
1
1
0

Example output:
? 4
1 2 3 4
? 2
1 2
? 2
1 3
? 2
1 4
? 2
2 4
? 2
3 4
Y 2
1 2

Example input:
4
4
3

Example output:
? 4
1 4 2 3
? 3
1 2 4
N 3
2 1 4

Editorial:
Denote by $$$e(A)$$$ the number of edges in a vertex set $$$A$$$, and by $$$e(A,B)$$$ the number of edges between $$$A$$$ and $$$B$$$. Note that $$$e(A,B) = e(A \cup B) - e(A) - e(B)$$$ can be answered by three queries.
Now we learn how to find an edge in this graph in logarithmic time. Given two sets $$$X$$$ and $$$Y$$$, such that $$$e(X,Y) \neq 0$$$, we can binary search on $$$X$$$, i.e. partition $$$X$$$ into disjoint $$$X_1$$$ and $$$X_2$$$ of roughly equal size. If $$$e(X_1, Y) \neq 0$$$, we continue to find an edge between $$$X_1$$$ and $$$Y$$$, otherwise certainly $$$e(X_2, Y) = e(X,Y) \neq 0$$$ and we can search for an edge between $$$X_2$$$ and $$$Y$$$. Once $$$|X| = 1$$$, we can do a similar binary search on $$$Y$$$. Finally, when both $$$|X| = 1$$$ and $$$|Y| = 1$$$ while $$$e(X,Y) \neq 0$$$, we have found an edge in graph G.
How do we use the above construction? We can find a spanning tree of graph $$$G$$$, as follows. Start with $$$S = \{1\}$$$ and find an edge between $$$S$$$ and $$$V \setminus S$$$. We remember this edge, add its second endpoint to $$$S$$$ and repeat until $$$S = V$$$.
Once we have a spanning tree, the task is much easier. As the knowledge of a spanning tree on a bipartite graph uniquely identifies the partitions (using a simple DFS, for instance), we can use two queries to determine whether the graph is bipartite or not. If it is, we have already found the partition and can report it. Otherwise, we can use similar binary search to find an edge in one of the partitions. Again, we use DFS to find the required cycle of odd length.
The total number of queries is roughly $$$6 N \log N$$$, as for each vertex, we perform two binary searches and each operation of binary search requires 3 queries. This totals up to 36000, which seems like too much. However, most of the time, one or two of the three queries have already been asked before and we can cache the answers. Furthermore, we can avoid asking queries of size 1 - we know that the answer is simply 0. With these optimisations, we can find out that the actual number of queries is actually around 17000 in the worst case.