This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "bits/extc++.h"
using namespace std;
template <typename T>
void dbgh(const T& t) {
cerr << t << endl;
}
template <typename T, typename... U>
void dbgh(const T& t, const U&... u) {
cerr << t << " | ";
dbgh(u...);
}
#ifdef DEBUG
#define dbg(...) \
cerr << "L" << __LINE__ << " [" << #__VA_ARGS__ << "]" \
<< ": "; \
dbgh(__VA_ARGS__)
#else
#define cerr \
if (false) \
cerr
#define dbg(...)
#endif
#define endl "\n"
#define long int64_t
#define sz(x) int((x).size())
mt19937 cowng(chrono::steady_clock::now().time_since_epoch().count());
int rint(int n) {
return int(cowng() % n);
}
int rint(int l, int r) {
return rint(r - l + 1) + l;
}
namespace d3 {
const int dx[] = {0, 0, 0, 0, -1, 1}, dy[] = {0, 0, -1, 1, 0, 0}, dz[] = {-1, 1, 0, 0, 0, 0};
}
namespace wrapper {
using namespace d3;
int n, m, k, q, queries;
vector<vector<vector<int>>> arrv, cache;
#ifdef GEN
void genrand() {
for (auto& a : arrv) {
for (auto& b : a) {
for (auto& c : b) {
c = cowng() % int(1e9);
}
}
}
}
#endif
bool ibs(int x, int y, int z) {
return 0 <= x && x < n && 0 <= y && y < m && 0 <= z && z < k;
}
void init(int _n, int _m, int _k, int _q) {
tie(n, m, k, q) = tie(_n, _m, _k, _q);
queries = 0;
cache.resize(n, vector<vector<int>>(m, vector<int>(k, -1)));
#ifdef GEN
arrv = cache;
genrand();
#endif
}
int query(int x, int y, int z) {
int& ans = cache[x][y][z];
if (ans != -1) {
return ans;
}
queries++;
assert(queries <= q);
#ifndef GEN
cout << "? " << x + 1 << " " << y + 1 << " " << z + 1 << endl;
cin >> ans;
#else
ans = arrv[x][y][z];
#endif
return ans;
};
int answer(int x, int y, int z) {
#ifdef GEN
cout << "queries: " << queries << endl;
for (int i = 0; i < 6; i++) {
int cx = x + dx[i], cy = y + dy[i], cz = z + dz[i];
if (ibs(cx, cy, cz)) {
assert(arrv[x][y][z] >= arrv[cx][cy][cz]);
}
}
#endif
cout << "! " << x + 1 << " " << y + 1 << " " << z + 1 << endl;
exit(0);
};
} // namespace wrapper
using wrapper::query, wrapper::answer, wrapper::ibs;
namespace s1 {
bool solve(int n, int m, int k, int q) {
#ifdef GEN
int ogrid[n];
for (auto& a : ogrid) {
a = rint(int(1e9));
}
#endif
if (m != 1 || k != 1) {
return false;
}
int cache[n];
memset(cache, -1, sizeof(cache));
auto queryuc = [&](int i) -> int {
#ifndef GEN
cout << "? " << i + 1 << " 1 1" << endl;
int x;
cin >> x;
return x;
#else
return ogrid[i];
#endif
};
auto query = [&](int i) -> int {
if (!(0 <= i && i < n)) {
return -1e9;
}
if (cache[i] != -1) {
return cache[i];
}
static int qcnt = 0;
qcnt++;
assert(qcnt <= q);
return cache[i] = queryuc(i);
};
auto answer = [&](int i) -> void {
cout << "! " << i + 1 << " 1 1" << endl;
exit(0);
};
auto check = [&](int i) -> void {
if (query(i) >= max(query(i - 1), query(i + 1))) {
dbg(query(i), query(i - 1), query(i + 1));
answer(i);
}
};
int l = 0, r = n - 1;
while ((r - l + 1) > 3) {
int madd = (r - l + 1) / 3, m1 = l + madd, m2 = r - madd;
dbg(l, r, m1, m2);
int a = query(m1), b = query(m2);
if (a < b) {
l = m1;
} else if (a == b) {
l = m1;
r = m2;
} else if (a > b) {
r = m2;
}
}
if (l == r) {
answer(l);
} else if (l + 1 == r) {
check(l);
answer(r);
} else {
check(l + 1);
check(l);
answer(r);
}
return true;
}
} // namespace s1
//#define GEN
namespace s2 {
using namespace d3;
bool solve(int n, int m, int l, int q) {
pair<int, array<int, 3>> opt {-1, {0, 0, 0}};
int iter = 500;
if (q == 3500) {
iter = 900;
}
auto upd = [&](int x, int y, int z) -> void {
opt = max(opt, pair<int, array<int, 3>> {query(x, y, z), {x, y, z}});
};
for (int i = 0; i < iter; i++) {
int x = rint(n), y = rint(m), z = rint(l);
upd(x, y, z);
}
auto [x, y, z] = opt.second;
int cnt[6] {};
deque<int> last;
while (true) {
int ord[6];
iota(begin(ord), end(ord), 0);
sort(begin(ord), end(ord), [&](int a, int b) -> bool {
return cnt[a] > cnt[b];
});
for (auto& k : ord) {
int cx = x + dx[k], cy = y + dy[k], cz = z + dz[k];
if (ibs(cx, cy, cz)) {
if (query(cx, cy, cz) > query(x, y, z)) {
cnt[k]++;
last.push_front(k);
if (sz(last) == 5) {
cnt[last.back()]--;
last.pop_back();
}
tie(x, y, z) = tie(cx, cy, cz);
goto loop;
}
}
}
answer(x, y, z);
return true;
loop:;
}
}
} // namespace s2
namespace s3 {
using namespace d3;
bool solve(int n, int m, int l, int q) {
if (q < int(1e5)) {
return false;
}
array<int, 4> opt {};
for (int i = 0; i < q / 2; i++) {
int x = rint(n), y = rint(m), z = rint(l);
opt = max(opt, {query(x, y, z), x, y, z});
}
auto [x, y, z, _] = opt;
while (true) {
for (int k = 0; k < 6; k++) {
int cx = x + dx[k], cy = y + dy[k], cz = z + dz[k];
if (ibs(cx, cy, cz) && query(cx, cy, cz) > query(x, y, z)) {
tie(x, y, z) = tie(cx, cy, cz);
goto loop;
}
}
answer(x, y, z);
return true;
loop:;
}
}
} // namespace s3
void solve() {
int n, m, k, q;
cin >> n >> m >> k >> q;
wrapper::init(n, m, k, q);
s1::solve(n, m, k, q) || s3::solve(n, m, k, q) || s2::solve(n, m, k, q);
}
int main() {
ios_base::sync_with_stdio(false);
cin.exceptions(ios::failbit);
solve();
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |