According to ancient Persian legends in Shahnameh, Zal, the legendary Persian hero, is madly in love with Rudaba, the princess of Kabul. When Zal asked for Rudaba's hand in marriage, her father gave him a challenge.

In Persia there are $n$ cities, labeled from $0$ to $n - 1$, and $m$ two-way roads, labeled from $0$ to $m - 1$. Each road connects a pair of distinct cities. Each pair of cities is connected by at most one road. Some of the roads are royal roads used for travels by royals. Zal's task is to determine which of the roads are the royal roads.

Zal has a map with all the cities and the roads in Persia. He does not know which of the roads are royal, but he can get help from Simurgh, the benevolent mythical bird who is Zal's protector. However, Simurgh does not want to reveal the set of royal roads directly. Instead, she tells Zal that the set of all royal roads is a golden set. A set of roads is a golden set if and only if:

* it has exactly $n - 1$ roads, and
* for every pair of cities, it is possible to reach one from the other by traveling only along the roads of this set.

Furthermore, Zal can ask Simurgh some questions. For each question:

1. Zal chooses a golden set of roads, and then
2. Simurgh tells Zal how many of the roads in the chosen golden set are royal roads.

Your program should help Zal find the set of royal roads by asking Simurgh at most $q$ questions. The grader will play the role of Simurgh.

Implementation details

You should implement the following procedure:

* int[] find\_roads(int n, int[] u, int[] v)
  + $n$: number of cities,
  + $u$ and $v$: arrays of length $m$. For all $0 \leq i \leq m - 1$, $u[i]$ and $v[i]$ are the cities connected by road $i$.
  + This procedure should return an array of length $n - 1$ containing the labels of the royal roads (in an arbitrary order).

Your solution can make at most $q$ calls to the following grader procedure:

* int count\_common\_roads(int[] r)
  + $r$: array of length $n - 1$ containing the labels of roads in a golden set (in an arbitrary order).
  + This procedure returns the number of royal roads in $r$.

Input

The sample grader reads the input in the following format:

* line 1: $n$ $m$ ($2 \leq n \leq 500$, $n - 1 \leq m \leq n \cdot (n - 1) / 2$)
* line $2 + i$ (for all $0 \leq i \leq m - 1$): $u[i]$ $v[i]$ ($0 \leq u[i], v[i] \leq n - 1$)
* line $2 + m$: $s[0], s[1], \ldots, s[n - 2]$

Here, $s[0], s[1], \ldots, s[n - 2]$ are the labels of the royal roads.

For all $0 \leq i \leq m - 1$, road $i$ connects two different cities (i.e., $u[i] \neq v[i]$).

There is at most one road between each pair of cities.

It is possible to travel between any pair of cities through the roads.

The set of all royal roads is a golden set.

find\_roads should call count\_common\_roads at most $q$ times. In each call, the set of roads specified by $r$ should be a golden set.

Output

The sample grader outputs 'YES', if find\_roads calls count\_common\_roads at most $30\,000$ times, and returns the correct set of royal roads. Otherwise, it outputs 'NO'.

Beware that the procedure count\_common\_roads in the sample grader does not check whether $r$ has all properties of a golden set. Instead, it counts and returns the number of labels of royal roads in the array $r$. However, if the program you submit calls count\_common\_roads with a set of labels that does not describe a golden set, the grading verdict will be 'Wrong Answer'.

Scoring

|  |  |  |
| --- | --- | --- |
| Subtask | Points | Additional Input Constraints |
| 1 | 13 | $n \leq 7$, $q = 30\,000$ |
| 2 | 17 | $n \leq 50$, $q = 30\,000$ |
| 3 | 21 | $n \leq 240$, $q = 30\,000$ |
| 4 | 19 | $q = 12\,000$ and there is a road between every pair of cities |
| 5 | 30 | $q = 8000$ |

Example

Input

```
4 6 30000
0 1
0 2
0 3
1 2
1 3
2 3
0 1 5
```

Output

```
OK
0 1 5
```

Note

The procedure count\_common\_roads in C++ uses the pass by reference method for efficiency reasons. You can still call the procedure in the usual way. The grader is guaranteed not to change the value of $r$.

find\_roads(4, [0, 0, 0, 1, 1, 2], [1, 2, 3, 2, 3, 3])

![](https://ioi.contest.codeforces.com/espresso/90d9774835e4e8208e0dd52e24b4b554a1bbdab0.png)

In this example there are $4$ cities and $6$ roads. We denote by $(a, b)$ a road connecting cities $a$ and $b$. The roads are labeled from $0$ to $5$ in the following order: $(0, 1)$, $(0, 2)$, $(0, 3)$, $(1, 2)$, $(1, 3)$, and $(2, 3)$. Every golden set has $n - 1 = 3$ roads.

Assume that the royal roads are the roads labeled $0$, $1$, and $5$, that is, the roads $(0, 1)$, $(0, 2)$, and $(2, 3)$. Then:

* count\_common\_roads([0, 1, 2]) returns $2$. This query is about roads labeled $0, 1$, and $2$, that is, roads $(0, 1)$, $(0, 2)$ and $(0,3)$. Two of them are royal roads.
* count\_common\_roads([5, 1, 0]) returns $3$. This query is about the set of all royal roads.

The procedure find\_roads should return $[5, 1, 0]$ or any other array of length $3$ that contains these three elements.

Note that the following calls are not allowed:

* count\_common\_roads([0, 1]): here the length of $r$ is not $3$.
* count\_common\_roads([0, 1, 3]): here $r$ does not describe a golden set, because it is impossible to travel from city $0$ to $3$ only using the roads $(0,1)$, $(0,2)$, $(1,2)$.

#include "simurgh.h"

#include <cstdio>
#include <cassert>
#include <vector>
#include <cstdlib>
#include <string>

using namespace std;

static const int CIPHER_SIZE = 64;
static const int CIPHER_KEY[CIPHER_SIZE] = {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0};

template<typename V>
static int xored(const V& c, int i) {
	return (int)c[i] ^ (CIPHER_KEY[i % CIPHER_SIZE] & 1);
}

static int MAXQ = 30000;

static int n, m, q = 0;
static vector<int> u, v;
static vector<bool> goal;
static vector<int> parent;

static int find(int node) {
	return (parent[node] == node ? node : parent[node] = find(parent[node]));
}

static bool merge(int v1, int v2) {
	v1 = find(v1);
	v2 = find(v2);
	if (v1 == v2)
		return false;
	parent[v1] = v2;
	return true;
}

static void wrong_answer() {
	printf("lxndanfdiadsfnslkj_output_simurgh_faifnbsidjvnsidjbgsidjgbs\n");
	printf("WA\n");
	printf("NO\n");
	exit(0);
}

static bool is_valid(const vector<int>& r) {
	if(int(r.size()) != n - 1)
		return false;

	for(int i = 0; i < n - 1; i++)
		if(r[i] < 0 || r[i] >= m)
			return false;

	parent.resize(n);
	for (int i = 0; i < n; i++) {
		parent[i] = i;
	}
	for (int i = 0; i < n - 1; i++) {
		if (!merge(u[r[i]], v[r[i]])) {
			return false;
		}
	}
	return true;
}

static int _count_common_roads_internal(const vector<int>& r) {
	if (!is_valid(r))
		wrong_answer();

	int common = 0;
	for(int i = 0; i < n - 1; i++) {
		bool is_common = goal[r[i]];
		is_common = xored(goal, r[i]);
		if (is_common)
			common++;
	}

	return common;
}

int count_common_roads(const vector<int>& r) {
	q++;
	if(q > MAXQ)
		wrong_answer();

	return _count_common_roads_internal(r);
}

int main() {
	{
		char secret[1000];
		assert(1 == scanf("%s", secret));
		if ((string)"wrslcnopzlckvxbnair_input_simurgh_lmncvpisadngpiqdfngslcnvd" != string(secret)) {
			printf("lxndanfdiadsfnslkj_output_simurgh_faifnbsidjvnsidjbgsidjgbs\n");
			printf("SV\n");
			return 0;
		}
	}
	assert(2 == scanf("%d %d", &n, &m));
	assert(1 == scanf("%d", &MAXQ));

	u.resize(m);
	v.resize(m);

	for(int i = 0; i < m; i++)
		assert(2 == scanf("%d %d", &u[i], &v[i]));

	goal.resize(m, false);

	for(int i = 0; i < n - 1; i++) {
		int id;
		assert(1 == scanf("%d", &id));
		goal[id] = true;
	}

	for (int i = 0; i < m; i++) {
		goal[i] = xored(goal, i);
	}

	vector<int> result = find_roads(n, u, v);

	if(_count_common_roads_internal(result) != n - 1)
		wrong_answer();

	printf("lxndanfdiadsfnslkj_output_simurgh_faifnbsidjvnsidjbgsidjgbs\n");
	printf("OK\n");
	for(int i = 0; i < (int)result.size(); i++){
		if(i)
			printf(" ");
		printf("%d", result[i]);
	}
	printf("\n");

	return 0;
}

#include <vector>

std::vector<int> find_roads(int n, std::vector<int> u, std::vector<int> v);
int count_common_roads(const std::vector<int>& r);

simurgh

Simurgh

Simurgh - Finding Spanning Tree


Jack and Jill play a game called Hotter, Colder. Jill has a number between $1$ and $N$, and Jack makes repeated attempts to guess it.

Each of Jack's guesses is a number between $1$ and $N$. In response to each guess, Jill answers hotter, colder or same. For Jack's first guess, Jill answers same. For the remaining guesses Jill answers:

* hotter if this guess is closer to Jill's number than his previous guess
* colder if this guess is farther from Jill's number than his previous guess
* same if this guess is neither closer to nor further from Jill's number than his previous guess.

You are to implement a procedure HC(N) that plays Jack's role. This implementation may repeatedly call Guess(G), with $G$ a number between $1$ and $N$. Guess(G) will return $1$ to indicate hotter, $-1$ to indicate colder or $0$ to indicate same. HC(N) must return Jill's number.

As example, assume $N=5$, and Jill has chosen the number $2$. When procedure HC makes the following sequence of calls to Guess, the results in the second column will be returned.

|  |  |  |
| --- | --- | --- |
| Call | Returned value | Explanation |
| Guess(5) | 0 | Same (first call) |
| Guess(3) | 1 | Hotter |
| Guess(4) | -1 | Colder |
| Guess(1) | 1 | Hotter |
| Guess(3) | 0 | Same |

At this point Jack knows the answer, and HC should return $2$. It has taken Jack $5$ guesses to determine Jill's number. You can do better.

Scoring

Subtask 1 [25 points]

HC(N) must call Guess(G) at most $500$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 2 [25 points]

HC(N) must call Guess(G) at most $18$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 3 [25 points]

HC(N) must call Guess(G) at most $16$ times. There will be at most $125\,250$ calls to HC(N), with N between $1$ and $500$.

Subtask 4 [up to 25 points]

Let $W$ be the largest integer, such that $2^W \le 3 N$. For this subtask your solution will score:

* $0$ points, if HC(N) calls Guess(G) $2W$ times or more
* $25\alpha$ points, where $\alpha$ is the largest real number, such that $0 < \alpha < 1$ and HC(N) calls Guess(G) at most $2W-\alpha W$ times,
* 25 points, if HC(N) calls Guess(G) at most $W$ times.

There will be at most $1\,000\,000$ calls to HC(N) with $N$ between $1$ and $500\,000\,000$.

Be sure to initialize any variables used by HC every time it is called.

#include "grader.h"
#include "hottercolder.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

static int moves, TT, NN, prev = -1;
int Guess(int x){
   int r;
   if (prev == -1 || abs(x-TT) == abs(prev-TT)) r = 0;
   else if (abs(x-TT) > abs(prev-TT)) r = -1;
   else r = 1;
   prev = x;
   if (x < 1 || x > NN) exit(92);
   moves++;
   return r;
}

int main(){
   int n=0,i,t,OK=0,sub1=0,sub2=0,sub3=0;
   double worst = 999999;
   while (2 == scanf("%d%d",&NN,&TT)) {
      if (NN > n) n = NN;
      prev = -1;
      moves = 0;
      int h = HC(NN);
      if (h != TT) {
         exit(91);
      }
      int W = floor(0.00001+log(3*NN)/log(2));
      double alpha = 2 - (double)moves/W;
      if (alpha < worst) worst = alpha;
       // 1 means failure
      if ( NN <= 500 && moves > 500 ) exit(93);
      if ( NN <= 500 && moves > 18 ) sub2=1;
      if ( NN <= 500 && moves > 16 ) sub3=1;
      OK++;
   }
   if (!sub1) printf("OK 1\n");
   if (!sub2) printf("OK 2\n");
   if (!sub3) printf("OK 3\n");
   if (worst > 0) printf("OK 4 alpha %0.2lf\n",worst);
   return 0;
}

#include "grader.h"

int HC(int N){
   int g = Guess(1);
   int h = Guess(N);
   if (g == 0) return N/2;
   if (g < 0) return N/4;
   if (g > 0) return 3*N/4;
}