| |
| #include <bits/stdc++.h> |
| #include <unistd.h> |
| #include <sys/wait.h> |
| #include <fcntl.h> |
| using namespace std; |
|
|
| int main(int argc, char* argv[]) { |
| int n = 100000, subtask = 3; |
| if (argc > 1) n = atoi(argv[1]); |
| if (argc > 2) subtask = atoi(argv[2]); |
|
|
| vector<int> ring(n); |
| iota(ring.begin(), ring.end(), 1); |
| mt19937 rng(42); |
| shuffle(ring.begin(), ring.end(), rng); |
|
|
| vector<int> pos(n+1); |
| for (int i = 0; i < n; i++) pos[ring[i]] = i; |
|
|
| vector<int> vis(n+2, 0); |
| int an = 0; |
|
|
| auto flip2 = [&](int u) -> int { |
| int pu = pos[u] + 1; |
| if ((vis[pu] ^= 1)) { |
| an += vis[pu-1] + vis[pu+1]; |
| } else { |
| an -= vis[pu-1] + vis[pu+1]; |
| } |
| return an || (vis[1] && vis[n]); |
| }; |
|
|
| int pipe_to_sol[2], pipe_from_sol[2]; |
| pipe(pipe_to_sol); |
| pipe(pipe_from_sol); |
|
|
| |
| int pipe_err[2]; |
| pipe(pipe_err); |
|
|
| pid_t pid = fork(); |
| if (pid == 0) { |
| close(pipe_to_sol[1]); |
| close(pipe_from_sol[0]); |
| close(pipe_err[0]); |
| dup2(pipe_to_sol[0], STDIN_FILENO); |
| dup2(pipe_from_sol[1], STDOUT_FILENO); |
| dup2(pipe_err[1], STDERR_FILENO); |
| close(pipe_to_sol[0]); |
| close(pipe_from_sol[1]); |
| close(pipe_err[1]); |
| execl("./debug_sol", "debug_sol", nullptr); |
| perror("execl"); |
| _exit(1); |
| } |
|
|
| close(pipe_to_sol[0]); |
| close(pipe_from_sol[1]); |
| close(pipe_err[1]); |
|
|
| |
| fcntl(pipe_err[0], F_SETFL, O_NONBLOCK); |
|
|
| FILE* to_sol = fdopen(pipe_to_sol[1], "w"); |
| FILE* from_sol = fdopen(pipe_from_sol[0], "r"); |
|
|
| auto readIntFrom = [&]() -> int { |
| int c = fgetc(from_sol); |
| while (c != '-' && (c < '0' || c > '9')) { |
| if (c == EOF) return -999; |
| c = fgetc(from_sol); |
| } |
| int sgn = 1; |
| if (c == '-') { sgn = -1; c = fgetc(from_sol); } |
| int x = 0; |
| while (c >= '0' && c <= '9') { x = x*10+(c-'0'); c = fgetc(from_sol); } |
| return x * sgn; |
| }; |
|
|
| int cnt_round = 0, cnt_query = 0; |
| auto start_time = chrono::steady_clock::now(); |
|
|
| fprintf(to_sol, "%d %d\n", subtask, n); |
| fflush(to_sol); |
|
|
| bool correct = false; |
| bool error = false; |
|
|
| while (true) { |
| int N = readIntFrom(); |
| if (N == -999) { fprintf(stderr, "EOF from solution\n"); error = true; break; } |
| if (N == -1) { |
| vector<int> ans(n); |
| for (int i = 0; i < n; i++) { |
| ans[i] = readIntFrom(); |
| if (ans[i] == -999) { error = true; break; } |
| } |
| if (error) break; |
|
|
| int opt = -1; |
| for (int i = 0; i < n; i++) if (ans[0] == ring[i]) { opt = i; break; } |
| if (opt == -1) { fprintf(stderr, "Answer vertex not in ring\n"); break; } |
|
|
| bool f1 = true, f2 = true; |
| for (int i = 1; i < n; i++) { |
| int op1 = (opt + i) % n; |
| int op2 = (opt - i + n) % n; |
| if (ring[op1] != ans[i]) f1 = false; |
| if (ring[op2] != ans[i]) f2 = false; |
| if (!f1 && !f2) break; |
| } |
| correct = f1 || f2; |
| break; |
| } |
|
|
| cnt_round++; |
| cnt_query += N; |
|
|
| vector<int> ops(N); |
| for (int i = 0; i < N; i++) { |
| ops[i] = readIntFrom(); |
| if (ops[i] == -999) { error = true; break; } |
| } |
| if (error) break; |
|
|
| for (int i = 0; i < N; i++) { |
| int res = flip2(ops[i]); |
| if (i > 0) fputc(' ', to_sol); |
| fprintf(to_sol, "%d", res); |
| } |
| fputc('\n', to_sol); |
| fflush(to_sol); |
| } |
|
|
| auto end_time = chrono::steady_clock::now(); |
| double elapsed = chrono::duration<double>(end_time - start_time).count(); |
|
|
| fclose(to_sol); |
| fclose(from_sol); |
|
|
| int status; |
| waitpid(pid, &status, 0); |
|
|
| |
| char errbuf[65536]; |
| string sol_stderr; |
| ssize_t nr; |
| while ((nr = read(pipe_err[0], errbuf, sizeof(errbuf)-1)) > 0) { |
| errbuf[nr] = 0; |
| sol_stderr += errbuf; |
| } |
| close(pipe_err[0]); |
|
|
| auto f = [](double x) -> double { return min(max(log2(x), 0.0), 8.0); }; |
| double lambda_val = max(0.0, 1.0 - 0.1 * (f(cnt_round / 18.0) + f(cnt_query / 1.5e7))); |
|
|
| printf("=== Solution Debug Output ===\n%s\n", sol_stderr.c_str()); |
| printf("=== Results ===\n"); |
| printf("Correct: %s\n", correct ? "YES" : "NO"); |
| printf("Rounds: %d\n", cnt_round); |
| printf("Queries: %d\n", cnt_query); |
| printf("Time: %.3f s\n", elapsed); |
| printf("Lambda: %.4f\n", lambda_val); |
|
|
| return correct ? 0 : 1; |
| } |
|
|