/*
* Solution with two mixed phases of dynamic size
* By "mixed" we mean that new types are also detected in the second phase.
* By "dynamic" we mean that #queries in the first phase is computed dynamically based on the current results.
*
* Author: Kian Mirjalali
*/
#include "mushrooms.h"
#include <cmath>
#include <algorithm>
#include <functional>
using namespace std;
#define allOf(c) ((c).begin()), ((c).end())
template<class C>
inline int largest_element_index(const vector<C>& v) {
return max_element(allOf(v), [](const C& c1, const C& c2) {return c1.size()<c2.size();}) - v.begin();
}
/**
* @returns ceil(a/b) for integers a, b
*/
template<class T>
inline T ceildiv(T a, T b) {
return (a+b-1)/b;
}
/**
* Finds minimum input of a function in range [begin, end).
* @param f a function : Integer -> Real
* @param begin
* @param end
* @returns Integer input which minimizes f
*/
inline int functionMinInput(function<double(int)> f, int begin, int end) {
int best = begin;
double fbest = f(best);
for (int i = begin+1; i < end; i++) {
const double fi = f(i);
if (fbest > fi) {
best = i;
fbest = fi;
}
}
return best;
}
typedef int Index;
typedef int SpeciesType;
const SpeciesType TYPE_0 = 0;
const SpeciesType TYPE_1 = 1;
typedef vector<Index> Indices;
class SpeciesTypes {
vector<Indices> typesIndices;
public:
inline SpeciesTypes(): typesIndices(2) {
}
inline void add(SpeciesType type, Index index) {
typesIndices[type].push_back(index);
}
inline const Indices& getIndices(SpeciesType type) const {
return typesIndices[type];
}
inline SpeciesType getLargestType() const {
return largest_element_index(typesIndices);
}
};
class SpeciesCounts {
vector<int> counts;
public:
inline SpeciesCounts(): counts({0, 0}) {
}
inline void add(SpeciesType type, int count=1, int otherCount=0) {
counts[type] += count;
counts[1-type] += otherCount;
}
inline int get(SpeciesType type) const {
return counts[type];
}
};
inline SpeciesType getType(Index i) {
return use_machine({0, i});
}
Index a, b;
SpeciesType ta;
inline vector<SpeciesType> getTypes(Index i, Index j) {
const int d = use_machine({a, i, b, j});
return {(d>>1)^ta, (d&1)^ta};
}
int count_mushrooms(int n) {
SpeciesTypes knownSpeciesTypes;
Index head = 0;
if (n >= 1) {
knownSpeciesTypes.add(TYPE_0, head);
head++;
if (n >= 2) {
const SpeciesType t1 = getType(head);
knownSpeciesTypes.add(t1, head);
head++;
if (n == 2 || t1 == TYPE_0) {
a = 0;
b = 1;
ta = TYPE_0;
} else {//n >= 3 && t1 == TYPE_1
const SpeciesType t2 = getType(head);
knownSpeciesTypes.add(t2, head);
head++;
if (t2 == TYPE_0) {
a = 0;
b = 2;
ta = TYPE_0;
} else {//t2 == TYPE_1
a = 1;
b = 2;
ta = TYPE_1;
}
}
}
}
const int maxk = int(2*sqrt(n));
while (head+2 <= n) {
const SpeciesType majType = knownSpeciesTypes.getLargestType();
const int majSize = knownSpeciesTypes.getIndices(majType).size();
const auto rem_queries_func = [n, head, majSize] (int k) -> double {
int l = 0;
for (int s = n-head-2*k; s > 0;) {
s -= max(majSize, k+ceildiv(head+l, 2));
l++;
}
return k + l;
};
const int k = functionMinInput(rem_queries_func, 0, maxk);
if (k == 0)
break;
const auto p = getTypes(head, head+1);
knownSpeciesTypes.add(p[0], head);
knownSpeciesTypes.add(p[1], head+1);
head += 2;
}
SpeciesCounts speciesCounts;
while (head < n) {
const SpeciesType majType = knownSpeciesTypes.getLargestType();
const Indices& majIndices = knownSpeciesTypes.getIndices(majType);
const int majSize = majIndices.size();
const int blockSize = min(majSize, n-head);
Indices v(2*blockSize);
for (int i = 0, j = 0; i < blockSize;) {
v[j++] = head++;
v[j++] = majIndices[i++];
}
const int differences = use_machine(v);
knownSpeciesTypes.add((differences&1)^majType, v[0]);
const int differents = (differences>>1);
const int same = blockSize-1-differents;
speciesCounts.add(majType, same, differents);
}
return knownSpeciesTypes.getIndices(TYPE_0).size()+speciesCounts.get(TYPE_0);
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
256 KB |
Output is correct |
2 |
Correct |
1 ms |
256 KB |
Output is correct |
3 |
Correct |
0 ms |
256 KB |
Output is correct |
4 |
Correct |
0 ms |
256 KB |
Output is correct |
5 |
Correct |
1 ms |
256 KB |
Output is correct |
6 |
Correct |
2 ms |
256 KB |
Output is correct |
7 |
Correct |
10 ms |
256 KB |
Output is correct |
8 |
Correct |
9 ms |
256 KB |
Output is correct |
9 |
Correct |
13 ms |
256 KB |
Output is correct |
10 |
Correct |
10 ms |
256 KB |
Output is correct |
11 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
12 |
Correct |
11 ms |
256 KB |
Output is correct |
13 |
Correct |
8 ms |
364 KB |
Output is correct |
14 |
Correct |
7 ms |
256 KB |
Output is correct |
15 |
Partially correct |
12 ms |
364 KB |
Output is partially correct |
16 |
Partially correct |
10 ms |
360 KB |
Output is partially correct |
17 |
Correct |
5 ms |
256 KB |
Output is correct |
18 |
Correct |
9 ms |
360 KB |
Output is correct |
19 |
Partially correct |
11 ms |
356 KB |
Output is partially correct |
20 |
Correct |
10 ms |
368 KB |
Output is correct |
21 |
Correct |
10 ms |
356 KB |
Output is correct |
22 |
Partially correct |
10 ms |
256 KB |
Output is partially correct |
23 |
Correct |
12 ms |
360 KB |
Output is correct |
24 |
Correct |
8 ms |
256 KB |
Output is correct |
25 |
Partially correct |
14 ms |
364 KB |
Output is partially correct |
26 |
Partially correct |
11 ms |
360 KB |
Output is partially correct |
27 |
Partially correct |
10 ms |
368 KB |
Output is partially correct |
28 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
29 |
Partially correct |
14 ms |
384 KB |
Output is partially correct |
30 |
Partially correct |
13 ms |
256 KB |
Output is partially correct |
31 |
Partially correct |
13 ms |
256 KB |
Output is partially correct |
32 |
Partially correct |
9 ms |
384 KB |
Output is partially correct |
33 |
Partially correct |
11 ms |
364 KB |
Output is partially correct |
34 |
Partially correct |
15 ms |
360 KB |
Output is partially correct |
35 |
Partially correct |
10 ms |
364 KB |
Output is partially correct |
36 |
Partially correct |
14 ms |
368 KB |
Output is partially correct |
37 |
Partially correct |
13 ms |
384 KB |
Output is partially correct |
38 |
Partially correct |
10 ms |
256 KB |
Output is partially correct |
39 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
40 |
Partially correct |
11 ms |
256 KB |
Output is partially correct |
41 |
Partially correct |
13 ms |
256 KB |
Output is partially correct |
42 |
Partially correct |
11 ms |
256 KB |
Output is partially correct |
43 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
44 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
45 |
Partially correct |
13 ms |
356 KB |
Output is partially correct |
46 |
Partially correct |
12 ms |
364 KB |
Output is partially correct |
47 |
Partially correct |
14 ms |
368 KB |
Output is partially correct |
48 |
Partially correct |
14 ms |
256 KB |
Output is partially correct |
49 |
Partially correct |
13 ms |
384 KB |
Output is partially correct |
50 |
Partially correct |
10 ms |
356 KB |
Output is partially correct |
51 |
Partially correct |
14 ms |
256 KB |
Output is partially correct |
52 |
Partially correct |
14 ms |
360 KB |
Output is partially correct |
53 |
Partially correct |
11 ms |
364 KB |
Output is partially correct |
54 |
Partially correct |
13 ms |
256 KB |
Output is partially correct |
55 |
Partially correct |
11 ms |
256 KB |
Output is partially correct |
56 |
Partially correct |
11 ms |
256 KB |
Output is partially correct |
57 |
Partially correct |
12 ms |
256 KB |
Output is partially correct |
58 |
Partially correct |
12 ms |
364 KB |
Output is partially correct |
59 |
Partially correct |
11 ms |
256 KB |
Output is partially correct |
60 |
Partially correct |
12 ms |
384 KB |
Output is partially correct |
61 |
Partially correct |
13 ms |
256 KB |
Output is partially correct |
62 |
Correct |
1 ms |
256 KB |
Output is correct |
63 |
Correct |
0 ms |
256 KB |
Output is correct |
64 |
Correct |
0 ms |
256 KB |
Output is correct |
65 |
Correct |
0 ms |
256 KB |
Output is correct |
66 |
Correct |
0 ms |
256 KB |
Output is correct |
67 |
Correct |
0 ms |
256 KB |
Output is correct |
68 |
Correct |
0 ms |
384 KB |
Output is correct |
69 |
Correct |
0 ms |
256 KB |
Output is correct |
70 |
Correct |
0 ms |
256 KB |
Output is correct |
71 |
Correct |
0 ms |
256 KB |
Output is correct |
72 |
Correct |
1 ms |
256 KB |
Output is correct |
73 |
Correct |
0 ms |
256 KB |
Output is correct |
74 |
Correct |
0 ms |
256 KB |
Output is correct |
75 |
Correct |
0 ms |
256 KB |
Output is correct |
76 |
Correct |
0 ms |
256 KB |
Output is correct |
77 |
Correct |
0 ms |
256 KB |
Output is correct |
78 |
Correct |
1 ms |
256 KB |
Output is correct |
79 |
Correct |
0 ms |
256 KB |
Output is correct |
80 |
Correct |
1 ms |
256 KB |
Output is correct |
81 |
Correct |
0 ms |
256 KB |
Output is correct |
82 |
Correct |
1 ms |
256 KB |
Output is correct |
83 |
Correct |
0 ms |
256 KB |
Output is correct |
84 |
Correct |
0 ms |
256 KB |
Output is correct |
85 |
Correct |
0 ms |
256 KB |
Output is correct |
86 |
Correct |
1 ms |
256 KB |
Output is correct |
87 |
Correct |
0 ms |
256 KB |
Output is correct |
88 |
Correct |
1 ms |
256 KB |
Output is correct |
89 |
Correct |
0 ms |
256 KB |
Output is correct |
90 |
Correct |
0 ms |
256 KB |
Output is correct |
91 |
Correct |
0 ms |
256 KB |
Output is correct |