File size: 2,863 Bytes
1fd0050
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>

using namespace std;

long long n, k;
map<pair<int, int>, long long> cache;

long long query(int r, int c) {
    if (r < 1 || r > n || c < 1 || c > n) {
        // This case should not be reached with valid logic.
        // It's a safeguard against out-of-bounds access.
        return -1; 
    }
    if (cache.count({r, c})) {
        return cache[{r, c}];
    }
    cout << "QUERY " << r << " " << c << endl;
    long long val;
    cin >> val;
    return cache[{r, c}] = val;
}

void done(long long ans) {
    cout << "DONE " << ans << endl;
}

void solve_min_pq() {
    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq;

    for (int i = 1; i <= n; ++i) {
        long long val = query(i, 1);
        pq.push({val, {i, 1}});
    }

    long long result = -1;
    for (int i = 0; i < k; ++i) {
        pair<long long, pair<int, int>> top = pq.top();
        pq.pop();
        result = top.first;
        int r = top.second.first;
        int c = top.second.second;

        if (c < n) {
            long long val = query(r, c + 1);
            pq.push({val, {r, c + 1}});
        }
    }
    done(result);
}

void solve_max_pq() {
    long long k_prime = n * n - k + 1;
    priority_queue<pair<long long, pair<int, int>>> pq;

    for (int i = 1; i <= n; ++i) {
        long long val = query(i, n);
        pq.push({val, {i, n}});
    }

    long long result = -1;
    for (int i = 0; i < k_prime; ++i) {
        pair<long long, pair<int, int>> top = pq.top();
        pq.pop();
        result = top.first;
        int r = top.second.first;
        int c = top.second.second;

        if (c > 1) {
            long long val = query(r, c - 1);
            pq.push({val, {r, c - 1}});
        }
    }
    done(result);
}

long long count_le(long long x) {
    long long count = 0;
    int r = 1, c = n;
    while (r <= n && c >= 1) {
        if (query(r, c) <= x) {
            count += c;
            r++;
        } else {
            c--;
        }
    }
    return count;
}

void solve_binary_search() {
    long long low = query(1, 1);
    long long high = query(n, n);
    long long ans = high;

    while (low <= high) {
        long long mid = low + (high - low) / 2;
        if (count_le(mid) >= k) {
            ans = mid;
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    done(ans);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> k;

    long long query_limit = 50000;
    
    if (n + k - 1 <= query_limit) {
        solve_min_pq();
    } 
    else if (n + (n * n - k + 1) - 1 <= query_limit) {
        solve_max_pq();
    }
    else {
        solve_binary_search();
    }

    return 0;
}