/*
Idea: randomization
Let's say we shuffle the elements and for m repetitions, find the shortest prefix that can form a stick.
We spend a total of m log(n * m) + sum |prefix| queries.
Let's try to find the expected value of |prefix|.
The expected value of |prefix| is n * m * max_n(min_m(random between 0 and 1))
max_n(min_m(random between 0 and 1))
= sum prob(max_n(min_m(random between 0 and 1)) > x)
= sum 1 - prob(max_n(min_m(random between 0 and 1)) < x)
= sum 1 - prob(min_m(random between 0 and 1) < x)^n
= sum 1 - (1 - prob(min_m(random between 0 and 1) > x))^n
= sum 1 - (1 - (1 - x)^m)^n
On the max test case (n = 400, m = 25):
=> 46266.455 (according to my graphing calculator)
=> Total number of queries: 46267 + m log(n * m) <= 46517 queries expected
*/
#include <bits/stdc++.h>
using namespace std;
#define sz(v) int(std::size(v))
#include "dango3.h"
vector<int> operator+(vector<int> one, const vector<int> two) {
one.insert(end(one), begin(two), end(two));
return one;
}
void Solve(int n, int m) {
vector<int> v(n * m);
iota(begin(v), end(v), 1);
mt19937 rng(1234);
for (int rep = 0; rep < m; rep++) {
for (int i = 0; i < sz(v); i++) swap(v[i], v[rng() % (i + 1)]);
int low = n, hi = sz(v);
while (low < hi) {
int mid = (low + hi) / 2;
if (Query(vector(begin(v), begin(v) + mid))) hi = mid;
else low = mid + 1;
}
vector<int> one, two;
for (int i = low - 1; i >= 0; i--) {
if (Query(vector(begin(v), begin(v) + i) + one)) two.push_back(v[i]);
else one.push_back(v[i]);
}
Answer(one);
v = two + vector(begin(v) + low, end(v));
}
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Correct |
1 ms |
348 KB |
Output is correct |
5 |
Correct |
0 ms |
348 KB |
Output is correct |
6 |
Correct |
0 ms |
348 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
604 KB |
Output is correct |
2 |
Correct |
2 ms |
348 KB |
Output is correct |
3 |
Correct |
2 ms |
348 KB |
Output is correct |
4 |
Correct |
3 ms |
348 KB |
Output is correct |
5 |
Correct |
2 ms |
348 KB |
Output is correct |
6 |
Correct |
3 ms |
348 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
22 ms |
612 KB |
Output is correct |
2 |
Correct |
29 ms |
604 KB |
Output is correct |
3 |
Correct |
26 ms |
604 KB |
Output is correct |
4 |
Correct |
24 ms |
604 KB |
Output is correct |
5 |
Correct |
27 ms |
620 KB |
Output is correct |
6 |
Correct |
34 ms |
616 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
102 ms |
700 KB |
Output is correct |
2 |
Correct |
100 ms |
704 KB |
Output is correct |
3 |
Correct |
102 ms |
704 KB |
Output is correct |
4 |
Correct |
100 ms |
600 KB |
Output is correct |
5 |
Correct |
101 ms |
704 KB |
Output is correct |
6 |
Correct |
113 ms |
612 KB |
Output is correct |