Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <functional>
- #include <numeric>
- #include <random>
- #include <map>
- using namespace std;
- #define int long long
- const int FSZ = 1e18;
- mt19937 rnd;
- int cntq=0;
- int ask(int id, int x) {
- cout << "? " << id + 1 << " " << x << endl;
- int ans;
- cin >> ans;
- ++cntq;
- return ans;
- }
- int n, L, value;
- vector<pair<int, int> > ans;
- int bs(int guy, int val, int l, int r){
- int ll=l, rr=r;
- while (rr - ll > 1){
- int mm = (ll+rr)/2;
- int res = ask(guy, mm);
- if (res == val) return mm;
- if (res < val) ll = mm;
- else rr = mm;
- }
- }
- pair<vector<int>, vector<int> > kth(vector<int> men, int as, int K, int l, int r){
- if (men.size() == 1){
- return {men, {}};
- }
- int R = rnd() % men.size();
- vector<int> left, eql, right;
- int V = bs(men[R], (L/n)*as, l, r);
- eql.push_back(men[R]);
- int C = (L/n)*as;
- for (int i=0; i < men.size(); i++){
- if (i==R) continue;
- int T = ask(men[i], V);
- if (T < C) right.push_back(men[i]);
- if (T == C) eql.push_back(men[i]);
- if (T > C) left.push_back(men[i]);
- }
- while (left.size() < K && eql.size()){
- left.push_back(eql.back());
- eql.pop_back();
- }
- if (left.size() == K){
- value = V;
- while (eql.size()){
- right.push_back(eql.back());
- eql.pop_back();
- }
- return {left, right};
- }
- if (left.size() < K){
- pair<vector<int>, vector<int> > p = kth(right, as, K-left.size(), l, r);
- while (left.size()){
- p.first.push_back(left.back());
- left.pop_back();
- }
- return p;
- }
- while (eql.size()){
- right.push_back(eql.back());
- eql.pop_back();
- }
- pair<vector<int>, vector<int> > p = kth(left, as, K, l, r);
- while (right.size()){
- p.second.push_back(right.back());
- right.pop_back();
- }
- return p;
- }
- void divide(int start, int l, int r, vector<int> men){
- if (men.size() == 1){
- ans[men[0]] = {l, r};
- return;
- }
- int F = men.size() / 2;
- int as = start+F;
- pair<vector<int>, vector<int> > p = kth(men, as, F, l, r);
- int V = value;
- divide(start, l, V, p.first);
- divide(start+p.first.size(), V, r, p.second);
- }
- signed main() {
- //ios_base::sync_with_stdio(false);
- cin >> n >> L;
- vector<int> men;
- for (int i=0; i < n;i++) men.push_back(i);
- ans.assign(n, {-1, -1});
- divide(0, 0, FSZ, men);
- cout << "!" << endl;
- for (int i = 0; i < n; ++i)
- cout << ans[i].first << " " << ans[i].second << endl;
- cerr << "Done " << cntq << " queries\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement