#include "mushrooms.h"
#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 7;
int dp[255][255][255];
int go(int known_a, int known_b, int qcnt);
pair<int,int> max_val(int known_a, int known_b, int qcnt) {
int v = 0, operation = 2;
// A.A.(...)
// B.B.(...)
for (int i : {2, known_a}) {
if (i > known_a)
continue;
int opt = inf;
for (int b = 0; b < 2 && opt > v; b++) {
if (i == 2) {
for (int a = 0; a < 2 && opt > v; a++)
opt = min(opt, i + go(known_a + (b ^ 1) + a, known_b + b + (a ^ 1), qcnt - 1));
} else {
opt = min(opt, i + go(known_a + (b ^ 1), known_b + b, qcnt - 1));
}
}
if (opt > v) {
v = opt;
operation = i == 2 ? 1 : 2;
}
}
int ok = 1;
// 000001111100
if (qcnt > 3) {
int cnt = 12, qry = 4;
if (known_a >= 7 && known_b >= 5) {
int opt = inf;
for (int a = 0; a <= cnt && opt > v; a++) {
if (qcnt > qry && cnt + known_b <= known_a && a != 0)
break;
int b = cnt - a;
opt = min(opt, cnt + go(known_a + a, known_b + b, qcnt - qry));
}
if (opt > v) {
v = opt;
operation = 3;
}
ok = 0;
}
}
// 00011
if (qcnt > 1 && ok) {
int cnt = 5, qry = 2;
if (known_a >= 3 && known_b >= 2) {
int opt = inf;
for (int a = 0; a <= cnt; a++) {
if (qcnt > qry && cnt + known_b <= known_a && a != 0)
break;
int b = cnt - a;
opt = min(opt, cnt + go(known_a + a, known_b + b, qcnt - qry));
}
if (opt > v) {
v = opt;
operation = 4;
}
}
}
return make_pair(v, operation);
}
int go(int known_a, int known_b, int qcnt) {
if (known_b > known_a)
swap(known_a, known_b);
if (qcnt == 0)
return 0;
if (known_a > 250)
return -inf;
if (~dp[known_a][known_b][qcnt])
return dp[known_a][known_b][qcnt];
int v = max_val(known_a, known_b, qcnt).first;
return dp[known_a][known_b][qcnt] = v;
}
vector<int> ind_a, ind_b;
int cnt_a = 0, cnt_b = 0;
void flip(int fl) {
if (fl) {
swap(ind_a, ind_b);
swap(cnt_a, cnt_b);
}
}
void askA(vector<int>& x) {
int len = int(x.size());
assert(int(ind_a.size()) >= len);
vector<int> cur;
for (int i = 0; i < len; i++)
cur.push_back(ind_a[i]), cur.push_back(x[i]);
int ret = use_machine(cur);
if (ret & 1) {
ind_b.push_back(x.back());
cnt_b++, ret--, len--;
} else {
ind_a.push_back(x.back());
cnt_a++, len--;
}
cnt_b += ret / 2;
cnt_a += len - (ret / 2);
if (ret == 0) {
for (int i = 0; i < len; i++)
ind_a.push_back(x[i]);
} else if (ret == len * 2) {
for (int i = 0; i < len; i++)
ind_b.push_back(x[i]);
}
}
const int qcnt_big = 4, len_big = 12;
vector<int> ord_big[qcnt_big] = {
{8, 0, 9, 10, 7, 11, 5, 1, 6, 4, 2, 3},
{3, 8, 4, 2, 1, 11, 5, 10, 6, 0, 9, 7},
{5, 7, 10, 1, 9, 3, 8, 6, 2, 11, 4, 0},
{2, 3, 11, 4, 6, 1, 9, 8, 7, 0, 5, 10}
};
vector<int> msk_big = {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
map<array<int,qcnt_big>,int> rev_big;
void askBig(vector<int>& x) {
assert(int(x.size()) == len_big);
int fl = int(ind_a.size()) < int(ind_b.size());
flip(fl);
array<int,qcnt_big> arr;
for (int i = 0; i < qcnt_big; i++) {
vector<int> x_ord;
for (int j = 0, ja = 0, jb = 0; j < len_big; j++) {
x_ord.push_back(msk_big[j] == 0 ? ind_a[ja++] : ind_b[jb++]);
x_ord.push_back(x[ord_big[i][j]]);
}
arr[i] = use_machine(x_ord);
}
int ans = rev_big[arr];
cnt_b += __builtin_popcount(ans);
cnt_a += len_big - __builtin_popcount(ans);
for (int i = 0; i < len_big; i++)
if ((ans >> i) & 1)
ind_b.push_back(x[i]);
else
ind_a.push_back(x[i]);
flip(fl);
}
const int qcnt_small = 2, len_small = 5;
vector<int> ord_small[qcnt_small] = {
{2, 3, 1, 0, 4},
{1, 2, 0, 4, 3}
};
vector<int> msk_small = {1, 1, 0, 0, 0};
map<array<int,qcnt_small>,int> rev_small;
void askSmall(vector<int>& x) {
assert(int(x.size()) == len_small);
int fl = int(ind_a.size()) < int(ind_b.size());
flip(fl);
array<int,qcnt_small> arr;
for (int i = 0; i < qcnt_small; i++) {
vector<int> x_ord;
for (int j = 0, ja = 0, jb = 0; j < len_small; j++) {
x_ord.push_back(msk_small[j] == 0 ? ind_a[ja++] : ind_b[jb++]);
x_ord.push_back(x[ord_small[i][j]]);
}
arr[i] = use_machine(x_ord);
}
int ans = rev_small[arr];
cnt_b += __builtin_popcount(ans);
cnt_a += len_small - __builtin_popcount(ans);
for (int i = 0; i < len_small; i++)
if ((ans >> i) & 1)
ind_b.push_back(x[i]);
else
ind_a.push_back(x[i]);
flip(fl);
}
void build() {
auto eval = [&](vector<int>& a, vector<int>& b) {
assert(int(a.size()) == int(b.size()));
int r = 0;
for (int i = 0, j = int(a.size()); i < j; i++)
r += int(a[i] != b[i]) + int(i + 1 != j ? b[i] != a[i+1] : 0);
return r;
};
for (int msk = 0; msk < (1 << len_small); msk++) {
array<int,qcnt_small> arr;
for (int it = 0; it < qcnt_small; it++) {
vector<int> ord;
for (int j = 0; j < len_small; j++)
ord.push_back((msk >> ord_small[it][j]) & 1);
arr[it] = eval(msk_small, ord);
}
rev_small[arr] = msk;
}
for (int msk = 0; msk < (1 << len_big); msk++) {
array<int,qcnt_big> arr;
for (int it = 0; it < qcnt_big; it++) {
vector<int> ord;
for (int j = 0; j < len_big; j++)
ord.push_back((msk >> ord_big[it][j]) & 1);
arr[it] = eval(msk_big, ord);
}
rev_big[arr] = msk;
}
}
void solve(int known_a, int known_b, int qcnt, int n) {
assert(qcnt >= 0);
int mx_unused = cnt_a + cnt_b;
if (mx_unused >= n)
return;
int fl = int(known_a < known_b);
if (fl)
swap(known_a, known_b);
flip(fl);
int operation = max_val(known_a, known_b, qcnt).second;
vector<int> x;
switch (operation) {
case 1: {
for (int i = 0; i < 2 && mx_unused + i < n; i++)
x.push_back(mx_unused + i);
askA(x);
qcnt--;
break;
}
case 2: {
for (int i = 0; i < known_a && mx_unused + i < n; i++)
x.push_back(mx_unused + i);
askA(x);
qcnt--;
break;
}
case 3: {
for (int i = 0; i < len_big && mx_unused + i < n; i++)
x.push_back(mx_unused + i);
if (int(x.size()) != len_big) {
askA(x);
qcnt--;
} else {
askBig(x);
qcnt -= qcnt_big;
}
break;
}
case 4: {
for (int i = 0; i < len_small && mx_unused + i < n; i++)
x.push_back(mx_unused + i);
if (int(x.size()) != len_small) {
askA(x);
qcnt--;
} else {
askSmall(x);
qcnt -= qcnt_small;
}
break;
}
}
flip(fl);
solve(int(ind_a.size()), int(ind_b.size()), qcnt, n);
}
int count_mushrooms(int n) {
memset(dp, -1, sizeof dp);
go(1, 0, 228);
build();
ind_a.push_back(0);
cnt_a = 1;
solve(1, 0, 228, n);
return cnt_a;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
324 ms |
65656 KB |
Output is correct |
2 |
Correct |
315 ms |
65632 KB |
Output is correct |
3 |
Correct |
333 ms |
65544 KB |
Output is correct |
4 |
Correct |
333 ms |
65656 KB |
Output is correct |
5 |
Correct |
322 ms |
65528 KB |
Output is correct |
6 |
Correct |
349 ms |
65684 KB |
Output is correct |
7 |
Correct |
358 ms |
65760 KB |
Output is correct |
8 |
Correct |
354 ms |
65784 KB |
Output is correct |
9 |
Correct |
333 ms |
65656 KB |
Output is correct |
10 |
Correct |
339 ms |
65784 KB |
Output is correct |
11 |
Correct |
332 ms |
65656 KB |
Output is correct |
12 |
Correct |
348 ms |
65784 KB |
Output is correct |
13 |
Correct |
332 ms |
65660 KB |
Output is correct |
14 |
Correct |
331 ms |
65528 KB |
Output is correct |
15 |
Correct |
320 ms |
65656 KB |
Output is correct |
16 |
Correct |
351 ms |
65656 KB |
Output is correct |
17 |
Correct |
334 ms |
65528 KB |
Output is correct |
18 |
Correct |
341 ms |
65784 KB |
Output is correct |
19 |
Correct |
345 ms |
65656 KB |
Output is correct |
20 |
Correct |
333 ms |
65784 KB |
Output is correct |
21 |
Correct |
353 ms |
65656 KB |
Output is correct |
22 |
Correct |
354 ms |
65784 KB |
Output is correct |
23 |
Correct |
326 ms |
65656 KB |
Output is correct |
24 |
Correct |
355 ms |
65528 KB |
Output is correct |
25 |
Correct |
347 ms |
65668 KB |
Output is correct |
26 |
Correct |
337 ms |
65788 KB |
Output is correct |
27 |
Correct |
318 ms |
65656 KB |
Output is correct |
28 |
Correct |
336 ms |
65656 KB |
Output is correct |
29 |
Correct |
324 ms |
65656 KB |
Output is correct |
30 |
Correct |
373 ms |
65800 KB |
Output is correct |
31 |
Correct |
345 ms |
65656 KB |
Output is correct |
32 |
Correct |
332 ms |
65656 KB |
Output is correct |
33 |
Correct |
330 ms |
65656 KB |
Output is correct |
34 |
Correct |
326 ms |
65784 KB |
Output is correct |
35 |
Correct |
317 ms |
65656 KB |
Output is correct |
36 |
Correct |
328 ms |
65784 KB |
Output is correct |
37 |
Correct |
317 ms |
65656 KB |
Output is correct |
38 |
Correct |
323 ms |
65784 KB |
Output is correct |
39 |
Correct |
334 ms |
65672 KB |
Output is correct |
40 |
Correct |
356 ms |
65704 KB |
Output is correct |
41 |
Correct |
331 ms |
65604 KB |
Output is correct |
42 |
Correct |
334 ms |
65784 KB |
Output is correct |
43 |
Correct |
318 ms |
65656 KB |
Output is correct |
44 |
Correct |
356 ms |
65784 KB |
Output is correct |
45 |
Correct |
322 ms |
65656 KB |
Output is correct |
46 |
Correct |
334 ms |
65660 KB |
Output is correct |
47 |
Correct |
331 ms |
65784 KB |
Output is correct |
48 |
Correct |
364 ms |
65672 KB |
Output is correct |
49 |
Correct |
319 ms |
65784 KB |
Output is correct |
50 |
Correct |
364 ms |
65684 KB |
Output is correct |
51 |
Correct |
317 ms |
65656 KB |
Output is correct |
52 |
Correct |
321 ms |
65684 KB |
Output is correct |
53 |
Correct |
327 ms |
65656 KB |
Output is correct |
54 |
Correct |
331 ms |
65788 KB |
Output is correct |
55 |
Correct |
335 ms |
65656 KB |
Output is correct |
56 |
Correct |
333 ms |
65784 KB |
Output is correct |
57 |
Correct |
338 ms |
65656 KB |
Output is correct |
58 |
Correct |
335 ms |
65656 KB |
Output is correct |
59 |
Correct |
330 ms |
65660 KB |
Output is correct |
60 |
Correct |
362 ms |
65656 KB |
Output is correct |
61 |
Correct |
323 ms |
65656 KB |
Output is correct |
62 |
Correct |
366 ms |
65540 KB |
Output is correct |
63 |
Correct |
353 ms |
65656 KB |
Output is correct |
64 |
Correct |
354 ms |
65656 KB |
Output is correct |
65 |
Correct |
351 ms |
65612 KB |
Output is correct |
66 |
Correct |
340 ms |
65656 KB |
Output is correct |
67 |
Correct |
364 ms |
65528 KB |
Output is correct |
68 |
Correct |
325 ms |
65528 KB |
Output is correct |
69 |
Correct |
353 ms |
65656 KB |
Output is correct |
70 |
Correct |
349 ms |
65656 KB |
Output is correct |
71 |
Correct |
351 ms |
65656 KB |
Output is correct |
72 |
Correct |
322 ms |
65528 KB |
Output is correct |
73 |
Correct |
326 ms |
65656 KB |
Output is correct |
74 |
Correct |
326 ms |
65528 KB |
Output is correct |
75 |
Correct |
328 ms |
65656 KB |
Output is correct |
76 |
Correct |
341 ms |
65656 KB |
Output is correct |
77 |
Correct |
337 ms |
65656 KB |
Output is correct |
78 |
Correct |
311 ms |
65528 KB |
Output is correct |
79 |
Correct |
330 ms |
65528 KB |
Output is correct |
80 |
Correct |
329 ms |
65544 KB |
Output is correct |
81 |
Correct |
321 ms |
65528 KB |
Output is correct |
82 |
Correct |
344 ms |
65528 KB |
Output is correct |
83 |
Correct |
328 ms |
65656 KB |
Output is correct |
84 |
Correct |
323 ms |
65528 KB |
Output is correct |
85 |
Correct |
335 ms |
65528 KB |
Output is correct |
86 |
Correct |
328 ms |
65528 KB |
Output is correct |
87 |
Correct |
337 ms |
65532 KB |
Output is correct |
88 |
Correct |
312 ms |
65528 KB |
Output is correct |
89 |
Correct |
322 ms |
65528 KB |
Output is correct |
90 |
Correct |
325 ms |
65528 KB |
Output is correct |
91 |
Correct |
314 ms |
65656 KB |
Output is correct |