Problem:
D: Complex Oracle - Complex Oracle -
問題
※この問題はリアクティブ問題です．すなわち，サーバー側に用意されたプログラムと対話的に応答することで正答を導くプログラムを作成する必要があります．
また、サーバー側のプログラムも計算機資源を共有する関係上、サーバーだけで最大 3 sec程度の実行時間、最大 300 MB程度のメモリを使用する場合がありますので、TLE・MLEにお気をつけください。
あいずにゃんは若ヶ松高校のプログラミングコンテスト部、通称ぷろこん部に所属する2年生である。見目麗しい。あいずにゃんはその小さな体も無限に存在するチャームポイントの1つであるが、本人はコンプレックスを感じているようだ。そのせいか、一列に並んでいる人たちを見ると、それぞれの人の前方にその人より身長が高い人が何人並んでいるかを瞬時に数えられる能力を持っている。
プロコンの名門・律命館大学中等部卒のエリート競技プログラマであり、ぷろこん部の部長であるりっつちゃんは、あいずにゃんのこの能力を使えば、並んでいる人たちがそれぞれ何番目に背が高いのかを当てることができるのではないかと考えた。
今、りっつちゃんは
N
人が並んでいる列をあいずにゃんに見せている。りっつちゃんは、人が
N
人並んでいることは知っているが、その並び順がどうなっているかはわからない。りっつちゃんはあいずにゃんに “
l
番目の人から
r
番目の人までコンプレックス度” を教えてもらうことができる。ここで、
l
番目の人から
r
番目の人までのコンプレックス度とは、
i
(
l \≤ i \≤ r
) 番目の人それぞれに関して、
l
番目から
i − 1
番目までの間にいる自分 (
i
) より背が高い人の人数の総和である。(より厳密な定義は入出力形式を参照のこと)
(うらやましいことに) ぷろこん部の部員であるあなたは、(とても、とても心苦しいが) あいずにゃんをオラクルとして利用することで身長順を当てるプログラムを書くようりっつちゃんに命じられた。つらい。せめてあいずにゃんに負担をかけないよう、少ない質問回数で求められるよう頑張ろう。
入力出力形式
サーバーは背の順を表す長さ
N
の数列
p
を保持している。これは入力として与えられない。
p
の各要素
p_i
は
1
以上
N
以下であり、それぞれ値は異なる。
p_i
が大きい値を持つ方が背が高いことを表す。
サーバーはまず、
p
の長さ
N
を表す
1
つの整数からなる
1
行を入力として解答プログラムに与える。
次に解答プログラムが
2
つの整数
l, r
(
1 \≤ l \≤ r \≤ N
) からなるクエリをサーバーに送る。クエリの出力形式は
?
l
r
である。これは例えばC/C++だと、
printf("? %d %d\n", l, r); fflush(stdout);
などと書けばよい。出力の度にフラッシュすることを推奨する。
すると、サーバー側は以下の値を表す
1
つの整数
C
からなる1行を入力として解答プログラムに与える。
C = (\{ (i, j) | p_i > p_j
{\rm for}
l \≤ i<j \≤ r \}の要素数)
ただし、クエリとして正しくない
l, r
(
l, r
が
1
以上
N
以下の数ではない、または
l>r
である) が与えられた場合、サーバーは
−1
を
C
として返す。
この応答を何度か繰り返し、解答プログラムが
p
を推定できたならば、
p
を以下の形式で出力する。
!
p_1
...
p_N
推定した順列の出力は1度しかできず、この出力が
p
と異なる場合、誤答となる。200,000回以内のクエリで正しい
p
を出力できた場合、正答となる。
各クエリで改行を行うよう気をつけること。
入力制約
1 \≤ N \≤ 100,000
推定される長さ
N
の数列
p
は順列。すなわち、
p_i \in \{1,
...
, N\}
{\rm for}
1 \≤  i \≤ N
、および
p_i \neq p_j
{\rm for}
1 \≤ i < j \≤ N
を満たす
サーバーへのクエリ回数は200,000回まで
サーバーから返答される
C
は32bit整数型では収まらない大きさになりうることに注意せよ
入力出力例
サーバーの出力
サーバーへの入力
4
? 1 3
2
? 2 4
1
...
...
! 4 1 3 2

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

using LL = long long; using ll = LL;
using PII = pair<int, int>; using pii = PII;
using PLL = pair<LL, LL>; using pll = PLL;
using VI = vector<int>; using VL = vector<LL>;
#define FOR(i,s,t) for(int i =s; i < t;i++)
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(),a.end()
#define debug(a) cout<<#a<<":="<<a<<endl;
#define int long long
struct BIT {
	int N, nn; vector<int> data;
	BIT(int n) {
		N = n + 1;
		data = vector<int>(n + 1, 0);
		nn = 1;
		while (nn * 2 <= N)nn *= 2;
	}
	void add(int i, int w) {
		i++;
		for (int x = i; x < N; x += x & -x) {
			data[x] += w;
		}
	}
	int sum(int i) { // [0,i)
		int ret = 0;
		for (int x = i; x > 0; x -= x & -x) {
			ret += data[x];
		}
		return ret;
	}
	// [l,r)
	int sum(int l, int r) {
		return sum(r) - sum(l);
	}
};

void solve() {
	int N;
	cin >> N;
	BIT bit(N);
	FOR(i, 0, N) {
		bit.add(i, 1);
	}
	LL kim = N;
	VI ans(N, -1);
	VI SET(N, 0);
	cout << "? 1 " << N<< endl;
	cin >> kim;
	for (int i = N - 1; i >= 1; i--) {
		cout << "? 1 " << i << endl;
		LL nx; cin >> nx;
		LL val = kim - nx + 1;
		int l = 0; int r = N;
		FOR(unchi, 0, 30) {
			int mid = (l + r) / 2;
			if (bit.sum(mid, N) >= val) {
				l = mid;
			}
			else r = mid;
		}
		ans[i] = l;
		SET[l] = 1;
		if (bit.sum(l, l + 1) == 1)bit.add(l, -1);
		kim = nx;
	}
	FOR(i, 0, N) {
		if (!SET[i])ans[0] = i;// , debug(i);
	}
	cout << "!";
	FOR(i, 0, N) {
		assert(ans[i] != -1);
		cout << " " << ans[i] + 1;
	}
	cout << endl;

}

signed main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);

	solve();

	return 0;
}
accuracy: 1
time_ms: 1260
memory_kb: 291740
final_rank: 3

code_snippet: // AOJ #2775 Complex Oracle
// 2025.3.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
struct Fenw {
    int n;
    vector<int> f;
    Fenw(int n): n(n), f(n+1,0){}
    void upd(int i, int d) {
        for(; i<=n; i+= i&-i) f[i]+=d;
    }
    int sum(int i) {
        int s=0;
        for(; i; i-= i&-i) s+=f[i];
        return s;
    }
    int kth(int k) {
        int idx = 0;
        for (int bit = 1 << 20; bit; bit >>= 1) {
            int nxt = idx + bit;
            if(nxt<=n && f[nxt] < k){
                k -= f[nxt];
                idx = nxt;
            }
        }
        return idx+1;
    }
};
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N; cin >> N;
    vector<ll> P(N+1,0), b(N+1,0);

    for(int i=2;i<=N;i++){
        cout << "? " << 1 << " " << i << "\n";
        cout.flush();
        ll r; cin >> r;
        P[i]=r;
    }
    b[1]=0;
    for(int i=2;i<=N;i++) b[i] = P[i]-P[i-1];

    Fenw fenw(N);
    for(int i=1;i<=N;i++) fenw.upd(i,1);

    vector<int> ans(N+1,0);
    for(int i=N;i>=1;i--){
        int sz = fenw.sum(N);
        int k = b[i] + 1;
        int pos = fenw.kth(sz - k + 1);
        ans[i] = pos;
        fenw.upd(pos, -1);
    }
    cout << "!";
    for(int i=1;i<=N;i++) cout << " " << ans[i];
    cout << endl;
    cout.flush();
    return 0;
}
accuracy: 1
time_ms: 1230
memory_kb: 291764
final_rank: 2

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 2775.cc: Complex Oracle
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 100000;

/* typedef */

typedef long long ll;

template <typename T>
struct BIT {
  int n;
  vector<T> bits;
  
  BIT() {}
  BIT(int _n) { init(_n); }

  void init(int _n) {
    n = _n;
    bits.assign(n + 1, 0);
  }

  T sum(int x) {
    x = min(x, n);
    T s = 0;
    while (x > 0) {
      s += bits[x];
      x -= (x & -x);
    }
    return s;
  }

  void add(int x, T v) {
    if (x <= 0) return;
    while (x <= n) {
      bits[x] += v;
      x += (x & -x);
    }
  }

  int lower_bound(T v) {
    int	k = 1;
    while ((k << 1) <= n) k <<=	1;
    int	x = 0;
    for	(; k > 0; k >>= 1)
      if (x + k <= n && bits[x + k] < v) {
        x += k;
        v -= bits[x];
      }
    return x + 1;
  }
};

/* global variables */

ll cs[MAX_N];
int ds[MAX_N], ps[MAX_N];
BIT<int> bit;

/* subroutines */

ll query(int i, int j) {
  printf("? %d %d\n", i + 1, j + 1); fflush(stdout);

  ll c;
  scanf("%lld", &c);
  return c;
}

/* main */

int main() {
  int n;
  scanf("%d", &n);

  cs[0] = 0;
  for (int i = 1; i < n; i++) {
    cs[i] = (ll)i * (i + 1) / 2 - query(0, i);
    ds[i] = cs[i] - cs[i - 1];
  }

  bit.init(n);
  for (int i = 1; i <= n; i++) bit.add(i, 1);

  for (int i = n - 1; i >= 0; i--) {
    int l = 0, r = n;
    while (l + 1 < r) {
      int m = (l + r) / 2;
      if (bit.sum(m) > ds[i]) r = m;
      else l = m;
    }

    ps[i] = r;
    bit.add(r, -1);
  }

  putchar('!');
  for (int i = 0; i < n; i++) printf(" %d", ps[i]);
  putchar('\n'); fflush(stdout);

  return 0;
}
accuracy: 1
time_ms: 1220
memory_kb: 291764
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (int i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}



void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int N;
	cin>>N;
	vector<ll> p(N);
	ll tmp=0;
	rep(i,N-1){
		cout<<"? 1 "<<i+2<<endl;
		ll a;
		cin>>a;
		p[i+1]=i+1-(a-tmp);
		tmp=a;
	}
	//vec_out(p);
	tmp=0;
	for(int i=N-2;i>=0;i--){
		cout<<"? "<<i+1<<" "<<N<<endl;
		ll a;
		cin>>a;
		p[i]+=a-tmp;
		tmp=a;
	}
	//vec_out(p);
	cout<<"!";
	rep(i,N){
		cout<<" "<<p[i]+1;
	}
	cout<<endl;
}
accuracy: 1
time_ms: 2190
memory_kb: 291716
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

// 1-indexed
template<typename T>
struct BIT{
    int n;
    vector<T> bit;
    BIT(int n_=0):n(n_),bit(n+1){}
    T sum(int i){
        T res=0;
        for(;i>0;i-=(i&-i))res+=bit[i];
        return res;
    }
    void add(int i,T a){
        if(i==0)return;
        for(;i<=n;i+=(i&-i)){bit[i]+=a;}
    }
    int lower_bound(T k){ // k<=sum(res)
        if(k<=0)return 0;
        int res=0,i=1;
        while((i<<1)<=n)i<<=1;
        for(;i;i>>=1){
            if(res+i<=n&&bit[res+i]<k)k-=bit[res+=i];
        }
        return res+1;
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<ll> query(n+1);
    BIT<int> bit(n+1);
    for(int i=1;i<=n;i++){
        cout << "? " << i << " " << n << endl;
        cin >> query[i];
        bit.add(i,1);
    }
    vector<int> res(n+1);
    for(int i=1;i+1<=n;i++){
        ll u=query[i]-query[i+1]+1;
        int id=bit.lower_bound(u);
        bit.add(id,-1);
        res[i]=id;
    }
    res[n]=bit.lower_bound(1);
    cout << "!";
    for(int i=1;i<=n;i++){
        cout << " " << res[i];
    }
    cout << endl;
}
accuracy: 1
time_ms: 1340
memory_kb: 291776
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

// 1-indexed
template<typename T>
struct BIT{
    int n;
    vector<T> bit;
    BIT(int n_=0):n(n_),bit(n+1){}
    T sum(int i){
        T res=0;
        for(;i>0;i-=(i&-i))res+=bit[i];
        return res;
    }
    void add(int i,T a){
        if(i==0)return;
        for(;i<=n;i+=(i&-i)){bit[i]+=a;}
    }
    int lower_bound(T k){ // k<=sum(res)
        if(k<=0)return 0;
        int res=0,i=1;
        while((i<<1)<=n)i<<=1;
        for(;i;i>>=1){
            if(res+i<=n&&bit[res+i]<k)k-=bit[res+=i];
        }
        return res+1;
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<int> query(n+1);
    BIT<int> bit(n+1);
    for(int i=1;i<=n;i++){
        cout << "? " << i << " " << n << endl;
        cin >> query[i];
        bit.add(i,1);
    }
    vector<int> res(n+1);
    for(int i=1;i+1<=n;i++){
        int u=query[i]-query[i+1]+1;
        int id=bit.lower_bound(u);
        bit.add(id,-1);
        res[i]=id;
    }
    res[n]=bit.lower_bound(1);
    cout << "!";
    for(int i=1;i<=n;i++){
        cout << " " << res[i];
    }
    cout << endl;
}
accuracy: 0.6176470588235294
time_ms: 30
memory_kb: 41248
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 0-indexed
template <class T>
struct SegmentTree {
  // a,b,c: T, e:T(unit)
  // abc = (ab)c = a(bc)
  // ae = ea = a
  typedef function<T(T, T)> F;
  int n;
  F f;
  T unit;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int newn, F f, T t) : f(f), unit(t) { init(newn); }
  SegmentTree(const vector<T> &v, F f, T t) : f(f), unit(t) {
    int _n = v.size();
    init(v.size());
    for (int i = 0; i < _n; ++i) dat[n + i] = v[i];
    for (int i = n - 1; i; --i) dat[i] = f(dat[i << 1], dat[(i << 1) | 1]);
  }
  void init(int newn) {
    n = 1;
    while (n < newn) n <<= 1;
    dat.assign(n << 1, unit);
  }

  // "go up" process
  void update(int k, T newdata) {
    dat[k += n] = newdata;
    while (k >>= 1) dat[k] = f(dat[k << 1], dat[(k << 1) | 1]);
  }
  // [a,b)
  T query(int a, int b) {
    T vl = unit, vr = unit;
    for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) vl = f(vl, dat[l++]);
      if (r & 1) vr = f(dat[--r], vr);
    }
    return f(vl, vr);
  }
  // require: func(unit) == false
  // min left: st <= res && func(seg.query(st,res + 1))
  template <typename C>
  int find_left(int st, C &func, T &acc, int k, int l, int r) {
    if (l + 1 == r) {
      acc = f(acc, dat[k]);
      return func(acc) ? l : -1;
    }
    int mid = (l + r) >> 1;
    if (mid <= st) return find_left(st, func, acc, (k << 1) | 1, mid, r);
    if (st <= l && !func(f(acc, dat[k]))) {
      acc = f(acc, dat[k]);
      return -1;
    }
    int nres = find_left(st, func, acc, (k << 1), l, mid);
    if (~nres) return nres;
    return find_left(st, func, acc, (k << 1) | 1, mid, r);
  }
  template <typename C>
  int find_left(int st, C &func) {
    T acc = unit;
    return find_left(st, func, acc, 1, 0, n);
  }

  // max right: res <= st && func(seg.query(res - 1,st))
  template <typename C>
  int find_right(int st, C &func, T &acc, int k, int l, int r) {
    if (l + 1 == r) {
      acc = f(dat[k], acc);
      return func(acc) ? r : -1;
    }
    int mid = (l + r) >> 1;
    if (st <= mid) return find_right(st, func, acc, k << 1, l, mid);
    if (r <= st && !func(f(dat[k], acc))) {
      acc = f(dat[k], acc);
      return -1;
    }
    int nres = find_right(st, func, acc, (k << 1) | 1, mid, r);
    if (~nres) return nres;
    return find_right(st, func, acc, k << 1, l, mid);
  }
  template <typename C>
  int find_right(int st, C &func) {
    T acc = unit;
    return find_right(st, func, acc, 1, 0, n);
  }
};

int n;
vector<long long> memo;

vector<int> solve();

int main() {
  cin >> n;
  memo.resize(n + 1);
  for (int i = 0; i < n - 1; ++i) {
    cout << "? " << i + 1 << " " << n << endl;
    cin >> memo[i];
  }
  auto res = solve();
  cout << "!";
  for (int i = 0; i < n; ++i) cout << " " << res[i] + 1;
  cout << endl;
  return 0;
}

vector<int> solve() {
  SegmentTree<int> seg(
      n, [](int l, int r) { return l + r; }, 0);
  vector<int> res(n);
  for (int i = 0; i < n; ++i) seg.update(i, 1);
  for (int i = 0; i < n; ++i) {
    int now = memo[i] - memo[i + 1] + 1;
    auto cmp = [&](int x) { return x >= now; };
    now = seg.find_left(0, cmp);
    res[i] = now;
    seg.update(now, 0);
  }
  return res;
}
accuracy: 1
time_ms: 1370
memory_kb: 291756
final_rank: 6

code_snippet: #pragma GCC optimize("O3")
#include<bits/stdc++.h> 
using namespace std;
using ll=long long;
using P=pair<ll,ll>;
template<class T> using V=vector<T>; 
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
const ll inf=(1e18);
//const ll mod=998244353;
const ll mod=1000000007;
ll GCD(ll a,ll b) {return b ? GCD(b,a%b):a;}
ll LCM(ll c,ll d){return c/GCD(c,d)*d;}
// struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>void debag(const vector<T> &a){cerr<<"debag :";for(auto v:a)cerr<<v<<" ";cerr<<"\n";}
template<class T>void print(const vector<T> &a){for(auto v:a)cout<<v<<" ";cout<<"\n";}
int main(){
      int n;
      cin>>n;
      V<ll> tmp(n),l(n);
      for(ll i=1;i<n;i++){
            cout<<"? "<<1<<" "<<i+1<<endl;
            ll v;
            cin>>v;
              tmp[i]=v;
              l[i]=i-(v-tmp[i-1]);
      }
  //    print(tmp);
      tmp.assign(n,0);
      V<ll> r(n);
      for(int i=n-2;i>=0;i--){
              cout<<"? "<<i+1<<" "<<n<<endl;
              ll v;
              cin>>v;
              tmp[i]=v;
              r[i]=v-tmp[i+1];
      }
      V<ll> ans(n);
      for(int i=0;i<n;i++){
            ans[i]=l[i]+r[i]+1;
      }
    //  print(l);
    //  print(r);
      cout<<"! ";
      for(int i=0;i<n;i++){
            cout<<ans[i];
            if(i==n-1){
                  cout<<endl;
            }else{
                  cout<<" ";
            }
      }
}
accuracy: 1
time_ms: 2240
memory_kb: 291776
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
using namespace std;
//#include<boost/multiprecision/cpp_int.hpp>
//#include<boost/multiprecision/cpp_dec_float.hpp>
//namespace mp=boost::multiprecision;
//#define mulint mp::cpp_int
//#define mulfloat mp::cpp_dec_float_100
//struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
#define INF (1<<30)
#define LINF (lint)(1LL<<56)
//#define endl "\n"
#define rep(i,n) for(lint (i)=0;(i)<(n);(i)++)
#define reprev(i,n) for(lint (i)=(n-1);(i)>=0;(i)--)
#define flc(x) __builtin_popcountll(x)
#define pint pair<int,int>
#define pdouble pair<double,double>
#define plint pair<lint,lint>
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define vec vector<lint>
#define nep(x) next_permutation(all(x))
typedef long long lint;
int dx[8]={1,1,0,-1,-1,-1,0,1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
const int MAX_N=3e5+5;
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return 1;}return 0;}
//vector<int> bucket[MAX_N/1000];
constexpr int MOD=1000000007;
//constexpr int MOD=998244353;
/*#include<atcoder/all>
using namespace atcoder;
typedef __int128_t llint;*/

template<typename U = unsigned, int B = 32>
class lazy_binary_trie {
    struct node {
        int cnt;
        U lazy;
        node *ch[2];
        node() : cnt(0), lazy(0), ch{ nullptr, nullptr } {}
    };
    void push(node* t, int b) {
        if ((t->lazy >> (U)b) & (U)1) swap(t->ch[0], t->ch[1]);
        if (t->ch[0]) t->ch[0]->lazy ^= t->lazy;
        if (t->ch[1]) t->ch[1]->lazy ^= t->lazy;
        t->lazy = 0;
    }
    node* add(node* t, U val, int b = B - 1) {
        if (!t) t = new node;
        t->cnt += 1;
        if (b < 0) return t;
        push(t, b);
        bool f = (val >> (U)b) & (U)1;
        t->ch[f] = add(t->ch[f], val, b - 1);
        return t;
    }
    node* sub(node* t, U val, int b = B - 1) {
        assert(t);
        t->cnt -= 1;
        if (t->cnt == 0) return nullptr;
        if (b < 0) return t;
        push(t, b);
        bool f = (val >> (U)b) & (U)1;
        t->ch[f] = sub(t->ch[f], val, b - 1);
        return t;
    }
    U get_min(node* t, U val, int b = B - 1) {
        assert(t);
        if (b < 0) return 0;
        push(t, b);
        bool f = (val >> (U)b) & (U)1; f ^= !t->ch[f];
        return get_min(t->ch[f], val, b - 1) | ((U)f << (U)b);
    }
    U get(node* t, int k, int b = B - 1) {
        if (b < 0) return 0;
        push(t, b);
        int m = t->ch[0] ? t->ch[0]->cnt : 0;
        return k < m ? get(t->ch[0], k, b - 1) : get(t->ch[1], k - m, b - 1) | ((U)1 << (U)b);
    }
    int count_lower(node* t, U val, int b = B - 1) {
        if (!t || b < 0) return 0;
        push(t, b);
        bool f = (val >> (U)b) & (U)1;
        return (f && t->ch[0] ? t->ch[0]->cnt : 0) + count_lower(t->ch[f], val, b - 1);
    }
    node *root;
public:
    lazy_binary_trie() : root(nullptr) {}
    int size() const {
        return root ? root->cnt : 0;
    }
    bool empty() const {
        return !root;
    }
    void insert(U val) {
        root = add(root, val);
    }
    void erase(U val) {
        root = sub(root, val);
    }
    void xor_all(U val) {
        if (root) root->lazy ^= val;
    }
    U max_element(U bias = 0) {
        return get_min(root, ~bias);
    }
    U min_element(U bias = 0) {
        return get_min(root, bias);
    }
    int lower_bound(U val) { // return id
        return count_lower(root, val);
    }
    int upper_bound(U val) { // return id
        return count_lower(root, val + 1);
    }
    U operator[](int k) {
        assert(0 <= k && k < size());
        return get(root, k);
    }
    int count(U val) {
        if (!root) return 0;
        node *t = root;
        for (int i = B - 1; i >= 0; i--) {
            push(t, i);
            t = t->ch[(val >> (U)i) & (U)1];
            if (!t) return 0;
        }
        return t->cnt;
    }
};

int main(void){
    int N;
    cin >> N;
    int ans[N];
    lint q[N];
    lazy_binary_trie<int,20> BT;
    rep(i,N) BT.insert(i+1);
    rep(i,N){
        cout << "? " << i+1 << " " << N << endl;
        cin >> q[i];
        if(i==0) continue;
        ans[i-1]=BT[q[i-1]-q[i]];
        BT.erase(ans[i-1]);
    }
    ans[N-1]=BT[0];
    cout << "! ";
    rep(i,N){
        cout << ans[i];
        if(i!=N-1) cout << " ";
    }
    cout << endl;
}
accuracy: 1
time_ms: 1400
memory_kb: 291776
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#include <ext/rope>
using namespace __gnu_cxx;


ll query(ll l, ll r){
    l++;
    printf("? %lld %lld\n", l, r); fflush(stdout);
    scanf("%lld", &l);
    return l;
}
void answer(vector<ll>a){
    putchar('!');
    for(ll i : a) printf(" %lld", i);
    puts("");
    exit(0);
}
int main(){
    ll n;
    scanf("%lld", &n);
    vector<ll> a(n + 1);
    for(ll i = 1; i <= n; i++) a[i] = query(0, i);
    rope<ll> x;
    for(ll i = n; i; i--) x.push_back(i);
    for(ll i = n; i; i--){
        auto p = x.mutable_begin() + (a[i] - a[i - 1]);
        a[i] = *p;
        x.erase(p);
    }
    a.erase(a.begin());
    answer(a);
}
accuracy: 1
time_ms: 1330
memory_kb: 291756
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long int lli;

int main(){
    int n;
    cin >> n;
    vector<lli> a(n), b(n);
    for(int i=0; i<n; i++){
        cout << "? " << 1 << " " << i+1 << endl;
        cin >> a[i];
        cout << "? " << i+1 << " " << n << endl;
        cin >> b[i];
    }
    for(int i=0; i<n-1; i++){
        a[n-1-i] -= a[n-2-i];
        b[i] -= b[i+1];
    }
    cout << "!";
    for(int i=0; i<n; i++){
        cout << " " << b[i]+1 +(i-a[i]);
    }
    cout << endl;
    return 0;
}
accuracy: 1
time_ms: 4650
memory_kb: 288960
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long int lli;

int main(){
    int n;
    cin >> n;
    vector<lli> a(n), b(n);
    for(int i=0; i<n; i++){
        cout << "? " << 1 << " " << i+1 << endl;
        cin >> a[i];
        cout << "? " << i+1 << " " << n << endl;
        cin >> b[i];
    }
    for(int i=n-2; i>=0; i--){
        a[i+1] -= a[i];
        b[n-i-2] -= b[n-i-1];
    }
    for(int i=0; i<n; i++){
        cout << a[i] << " " << b[i] << endl;
    }
    cout << "!";
    for(int i=0; i<n; i++){
        cout << " " << b[i]+1 +(i-a[i]);
    }
    cout << endl;
    return 0;
}
accuracy: 0.6176470588235294
time_ms: 130
memory_kb: 12140
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(i,n) for (int i = 0; i < (n); ++i)
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const ll INF=1LL<<60;
const int inf=(1<<30)-1;
const int mod=1e9+7;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;cin >> n;
    vector<int> p(n);
    vector<ll> l(n+1),r(n+1);
    for(int i=2;i<=n;i++){
        cout << "? " << 1 << " " << i << endl;
        cin >> l[i];
    }
    for(int i=1;i<=n-1;i++){
        cout << "? " << i << " " << n << endl;
        cin >> r[i-1];
    }
    for(int i=0;i<n;i++){
        ll u=l[i+1]-l[i];
        ll v=r[i]-r[i+1];
        p[i]=i-u+v;
    }
    cout << '!';
    for(int i=0;i<n;i++){
        cout << " " << p[i]+1;
    }
    cout << endl;
}
accuracy: 1
time_ms: 4600
memory_kb: 288900
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int64_t question(int l, int r){
    cout << "? " << l + 1 << " " << r + 1 << endl;
    int64_t res;
    cin >> res;
    return res;
}

void output(vector<int> &A){
    cout << "!";
    for (const auto &a: A)
        cout << " " << a;
    cout << endl;
}

ll INF = 1e9+7;
ll N, dat[2222222];
void init(ll k){
    N = 1;
    while(N < k) N *= 2;
    for(ll i=0;i<2*N-1;i++) dat[i] = 0;
}

void update(ll k, ll num){
    k += N-1;
    dat[k] = num;
    while(k>0){
        k = (k-1)/2;
        dat[k] = dat[k*2 + 1] + dat[k*2+2];
    }
}

// query(a,b,0,0,n) → [a,b)
ll query(ll a, ll b, ll k, ll l, ll r){
    if(r<=a || b<=l) return 0;
    if(a<=l && r<=b) return dat[k];
    else{
        ll vl = query(a,b,k*2+1,l,(l+r)/2);
        ll vr = query(a,b,k*2+2,(l+r)/2,r);
        return vl+vr;
    }
}


signed main(){
    ios::sync_with_stdio(false);
	cin.tie(0);
    cout << fixed << setprecision(20);

    int n;
    cin >> n;
    vector<int64_t> D(n);
    int64_t prev = 0;
    for (int i = 1; i < n; i++){
        auto res = question(0, i);
        D[i] = res - prev;
        prev = res;
    }
    init(n + 1);

    auto check = [&](auto k, auto d){
        return d < query(k, n + 1, 0, 0, N);
    };

    auto b_serach = [&](auto ok, auto ng, auto check, auto d){
        while (abs(ok - ng) > 1){
            auto mid = (ok + ng) / 2;
            (check(mid, d) ? ok : ng) = mid;
        }
        return ok;
    };

    for (int i = 1; i <= n; i++)
        update(i, 1);
    vector<int> ans(n);
    
    for (int i = n - 1; i >= 0; i--){
        int res = b_serach(0, n + 2, check, D[i]);
        update(res, 0);
        ans[i] = res;
    }

    output(ans);
}
accuracy: 1
time_ms: 2680
memory_kb: 288908
final_rank: 13

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-8;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

class Add_Segment_Tree {
	vector<long long int>v;
	vector<long long int>add;
	vector<long long int>modi;
	vector<int>l;
	vector<int>r;
	int num;
	long long int ret;
	void Left(int place) {
		if (place >= v.size() / 2) {
			l[place] = place - v.size() / 2;
			return;
		}
		Left(place * 2);
		Left(place * 2 + 1);
		l[place] = l[place * 2];
		return;
	}
	void Right(int place) {
		if (place >= v.size() / 2) {
			r[place] = place - v.size() / 2;
			return;
		}
		Right(place * 2);
		Right(place * 2 + 1);
		r[place] = r[place * 2 + 1];
		return;
	}
	long long int Update(int place) {
		if (place >= v.size() / 2) {
			return v[place];
		}
		v[place] = Update(place * 2) + Update(place * 2 + 1);
		return v[place];
	}
	void Modify(int a, int b, long long int num, int place) {
		if (l[place] >= a && r[place] <= b) {
			modi[place] = num * (r[place] - l[place] + 1);
			v[place] = num * (r[place] - l[place] + 1);
			add[place] = 0;
			return;
		}
		if (l[place] > b || r[place] < a)return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Modify(a, b, num, place * 2);
		Modify(a, b, num, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
	void Add(int a, int b, long long int num, int place) {
		if (l[place] >= a && r[place] <= b) {
			if (modi[place] != LLONG_MAX) {
				if (place * 2 < v.size()) {
					modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
					v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
					add[place * 2] = add[place * 2 + 1] = 0;
				}
				modi[place] = LLONG_MAX;
			}
			add[place] += num * (r[place] - l[place] + 1);
			return;
		}
		if (l[place] > b || r[place] < a)return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Add(a, b, num, place * 2);
		Add(a, b, num, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
	void Sum(int a, int b, int place) {
		if (l[place] >= a && r[place] <= b) {
			if (modi[place] != LLONG_MAX) {
				if (place * 2 < v.size()) {
					modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
					v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
					add[place * 2] = add[place * 2 + 1] = 0;
				}
				modi[place] = LLONG_MAX;
			}
			ret += v[place] + add[place];
			return;
		}
		if (l[place]>b || r[place]<a) return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Sum(a, b, place * 2);
		Sum(a, b, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
public:
	Add_Segment_Tree(int n) {
		n++;
		num = 1;
		while (num < n * 2) {
			num *= 2;
		}
		l.resize(num);
		r.resize(num);
		v.resize(num, 0);
		add.resize(num, 0);
		modi.resize(num, LLONG_MAX);
		Left(1);
		Right(1);
	}
	void Insert(int place, long long int num, bool update) {
		place += v.size() / 2;
		v[place] = num;
		if (!update)return;
		place /= 2;
		while (place) {
			v[place] = v[place * 2] + v[place * 2 + 1];
			place /= 2;
		}
	}
	void Modify(int a, int b, long long int num) {
		Modify(a, b, num, 1);
	}
	void Add(int a, int b, long long int num) {
		Add(a, b, num, 1);
	}
	void Init() {
		Update(1);
	}
	long long int Sum(int a, int b) {
		ret = 0;
		Sum(a, b, 1);
		return ret;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	//Add_Segment_Tree asg(N);
	Add_Segment_Tree num(N);
	for (int i = 0; i < N; i++) {
		//asg.Add(i, i, N - i);
		num.Add(i, i, 1);
	}
	long long int bef = 0;
	cout << "? 1 " << N << endl;
	cin >> bef;
	vector<int>ans(N);
	for (int i = N - 2; i >= 0; i--) {
		cout << "? 1 " << i + 1 << endl;
		long long int c;
		cin >> c;
		//int box= asg.Sum(bef - c, bef - c);
		int bag = i + 2 - (bef-c);
		L = 0;
		R = N;
		//cout << "bag " <<bag<< endl;
		while (R - L > 1) {
			int mid = (R + L) / 2;
			if (num.Sum(1, mid) < bag)L = mid;
			else R = mid;
		}
		ans[i + 1] = R;
	//	asg.Add(bef-c, N, -1);
		num.Add(ans[i + 1], ans[i+1], -1);
		bef = c;
	}
	long long int nx = N * (N + 1) / 2 - accumulate(ans.begin(), ans.end(), 0LL);
	ans[0] = nx;
	cout << "!";
	for (auto i : ans)cout << " " << i;
	cout << endl;
}
accuracy: 1
time_ms: 3610
memory_kb: 288956
final_rank: 14

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;
 
int main() {
    int N; scanf("%d", &N);

    vector<int> A(N), B(N);
    ll pre = 0;
    for(int i=0; i<N; i++) {
        printf("? %d %d\n", 1, i+1);
        fflush(stdout);
        
        ll v; scanf("%lld", &v);
        A[i] = i - (v - pre);
        pre = v;
    }

    pre = 0;
    for(int i=N-1; i>=0; i--) {
        printf("? %d %d\n", i+1, N);
        fflush(stdout);

        ll v; scanf("%lld", &v);
        B[i] = v - pre;
        pre = v;
    }

    printf("!");
    for(int i=0; i<N; i++) printf(" %d", A[i] + B[i] + 1);
    printf("\n");
    fflush(stdout);
    return 0;
}
accuracy: 1
time_ms: 2600
memory_kb: 288952
final_rank: 12

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100000

ll to_N[NUM+1],from_1[NUM+1],ans[NUM+1];


int main(){

	ll N;
	scanf("%lld",&N);

	to_N[N] = 0;
	for(ll left = N-1; left >= 1; left--){
		printf("? %lld %lld\n",left,N); fflush(stdout);
		scanf("%lld",&to_N[left]);
	}

	from_1[1] = 0;

	for(int right = 2; right <= N; right++){
		printf("? 1 %d\n",right); fflush(stdout);
		scanf("%lld",&from_1[right]);
	}

	ans[1] = to_N[1]-to_N[2]+1;
	for(int i = 2; i <= N-1; i++){
		ans[i] = (to_N[i]-to_N[i+1])+((ll)i-(from_1[i]-from_1[i-1]+1))+1;
	}
	ans[N] = N-(from_1[N]-from_1[N-1]+1)+1;

	printf("!");
	for(int i = 1; i <=N; i++)printf(" %lld",ans[i]);
	printf("\n");

	return 0;
}
accuracy: 1
time_ms: 4670
memory_kb: 288940
final_rank: 17

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100000

ll to_N[NUM+1],from_1[NUM+1],ans[NUM+1];


int main(){

	ll N;
	scanf("%lld",&N);

	to_N[N] = 0;
	//右端にかけてのクエリを投げる<ans[left]より右にある小さい数の個数>
	for(ll left = N-1; left >= 1; left--){
		printf("? %lld %lld\n",left,N); fflush(stdout);
		scanf("%lld",&to_N[left]);
	}

	from_1[1] = 0;
	//左端からのクエリを投げる
	for(int right = 2; right <= N; right++){
		printf("? 1 %d\n",right); fflush(stdout);
		scanf("%lld",&from_1[right]);
	}

	ans[1] = to_N[1]-to_N[2]+1;	 //自分の右にある、自分より小さい数の個数+1
	for(int i = 2; i <= N-1; i++){
		ans[i] = (to_N[i]-to_N[i+1])+((ll)i-(from_1[i]-from_1[i-1]+1))+1; //自分の右にある、自分より小さい数の個数+自分の左にある、自分より小さい数の個数+1
	}
	ans[N] = N-(from_1[N]-from_1[N-1]+1)+1;

	printf("!");
	for(int i = 1; i <=N; i++)printf(" %lld",ans[i]);
	printf("\n");

	return 0;
}
accuracy: 1
time_ms: 4700
memory_kb: 288940
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct BIT{
    // [1,n]
    int n; vector<ll> bit;
    // ?????????
    BIT(int _n){
        n = _n;
        bit = vector<ll>(n+1,0);
    }
    // sum of [1,i]
    ll sum(int i){
        ll s = 0;
        while(i>0){
            s += bit[i];
            i -= i & -i;
        }
        return s;
    }
    // add x in i-th element
    void add(int i, ll x){
        while(i<=n){
            bit[i] += x;
            i += i & -i;
        }
    }
};

ll query(int x)
{
    printf("? 1 %d\n", x); fflush(stdout);
    ll ret;
    scanf(" %lld", &ret);
    return ret;
}

int main()
{
    int n;
    scanf(" %d", &n);

    vector<int> ans(n);

    BIT bit(n);
    for(int i=1; i<=n; ++i) bit.add(i,1);

    ll x = query(n);
    for(int i=n-1; i>0; --i)
    {
        ll y = query(i);
        ll diff = x-y;

        int l=0, r=n;
        while(r-l>1)
        {
            int m = (l+r)/2;
            if(bit.sum(n)-bit.sum(m)<=diff) r=m;
            else l=m;
        }

        // dbg(l);dbg(r);
        ans[i] = r;
        bit.add(r,-1);
        x = y;
    }

    for(int i=1; i<=n; ++i) if(bit.sum(i)-bit.sum(i-1)>0) ans[0] = i;

    printf("!");
    rep(i,n) printf(" %d", ans[i]);
    printf("\n");
    return 0;
}
accuracy: 1
time_ms: 1660
memory_kb: 288940
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

template<typename T>
class BIT {
private:
  vector<T> bit;
  int n;
public:
  BIT(int _n) : n(_n) {
    bit = vector<T>(n+1, 0);
  }
  void add(int v, T a){ //0-indexed
    for(int x=v+1; x<=n; x += x&(-x)) bit[x] += a;
  }
  T sum(int v){ //0-indexed
    T ret=0;
    for(int x=v+1; x>0; x -= x&(-x)) ret += bit[x];
    return ret;
  }
  int lower_bound(T w){ //wテ、ツサツ・テ、ツクツ甘」ツ?ィテ」ツ?ェテ」ツつ凝ヲツ慊?・ツーツ湘」ツ?ョsumテ」ツ?ョテ、ツスツ催ァツスツョ(0-indexed)
    if(w<=0) return 0;
    int x=0, d=0;
    while(n > (1<<d)) d++;
    for(int k=(1<<(d-1)); k>0; k/=2){
      if(x+k<=n && bit[x+k]<w){
        w -= bit[x+k];
        x += k;
      }
    }
    return x;
  }
};

vector<int> ans;

long ask(int l, int r){
  cout << "? " << l << " " << r << endl;
  if(ans.size()>0){
    l--;
    long ret = 0;
    rep(i,l,r)rep(j,l,i) if(ans[j] > ans[i]) ret++;
    return ret;
  } else {
    long d;
    cin>>d;
    return d;
  }
}

int main(int argc, char* argv[]){
  if(argc>2){
    rep(i,1,argc) ans.pb(atoi(argv[i]));
    dbg(ans);
  }

  int n;
  cin>>n;

  vector<long> acc(n);
  acc[0] = 0;
  rep(i,1,n){
    acc[i] = ask(1,i+1);
  }
  vector<long> val(n);
  val[0] = 0;
  rep(i,1,n) val[i] = acc[i] - acc[i-1];

  BIT<int> bit(n+1);
  rep(i,n) bit.add(i+1,1);

  vector<int> res(n);
  for(int i=n-1; i>=0; i--){//dbg(i,val[i]);
    int idx = bit.lower_bound(i+1-val[i]);
    res[i] = idx;
    bit.add(idx, -1);
  }

  cout << "!";
  rep(i,n) cout << " " << res[i];
  cout<<endl;

  return 0;
}
accuracy: 1
time_ms: 1700
memory_kb: 288896
final_rank: 9