답안 #886834

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
886834 2023-12-13T03:22:54 Z box Super Dango Maker (JOI22_dango3) C++17
100 / 100
113 ms 704 KB
/*
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