結果
| 問題 |
No.2577 Simple Permutation Guess
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-12-05 01:44:50 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 188 ms / 2,000 ms |
| コード長 | 3,739 bytes |
| コンパイル時間 | 3,559 ms |
| コンパイル使用メモリ | 253,940 KB |
| 実行使用メモリ | 25,452 KB |
| 平均クエリ数 | 248.84 |
| 最終ジャッジ日時 | 2024-09-26 23:54:27 |
| 合計ジャッジ時間 | 17,614 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 111 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct BIT {
int n;
std::vector<T> tree;
BIT(int n) : n(n) {
tree.assign(n + 1, T(0));
}
BIT() {}
T _sum(int i) {
i++;
T res = T(0);
while (i > 0) {
res += tree[i];
i -= i & -i;
}
return res;
}
T sum(int l, int r) {
return _sum(r - 1) - _sum(l - 1);
}
T sum(int r) {
return _sum(r - 1);
}
T get(int i) {
return _sum(i) - _sum(i - 1);
}
void add(int i, T x) {
i++;
while (i <= n) {
tree[i] += x;
i += i & -i;
}
}
int lower_bound(T x) {
int pos = 0;
int plus = 1;
while (plus * 2 <= n) plus *= 2;
while (plus > 0) {
if ((pos + plus <= n) && (tree[pos + plus] < x)) {
x -= tree[pos + plus];
pos += plus;
}
plus >>= 1;
}
return pos;
}
};
struct Factoradic : std::vector<int> {
using std::vector<int>::vector;
void shrink() {
while (this->size() >= 2u && !this->back()) {
this->pop_back();
}
}
Factoradic &operator+=(const Factoradic &rhs) {
this->resize(std::max(this->size(), rhs.size()) + 1);
for (size_t i = 0; i < rhs.size(); ++i) {
(*this)[i] += rhs[i];
}
for (size_t i = 0; i + 1 < this->size(); ++i) {
if ((*this)[i] >= i + 1) {
(*this)[i + 1] += (*this)[i] / (i + 1);
(*this)[i] -= (i + 1);
}
}
shrink();
return *this;
}
Factoradic &operator/=(int rhs) {
for (int i = int(this->size()) - 1; i >= 0; --i) {
if (i) {
(*this)[i - 1] += (*this)[i] % rhs * i;
}
(*this)[i] /= rhs;
}
shrink();
return *this;
}
Factoradic operator+(const Factoradic &rhs) const {
Factoradic ret = *this;
ret += rhs;
return ret;
}
Factoradic operator/(int rhs) const {
Factoradic ret = *this;
ret /= rhs;
return ret;
}
std::vector<int> to_permutation(int digit = -1) const {
if (digit == -1) digit = int(this->size());
assert(int(this->size()) <= digit);
BIT<int> bit(digit);
for (int i = 0; i < digit; ++i) {
bit.add(i, 1);
}
std::vector<int> ret;
ret.reserve(digit);
for (int i = digit - 1; i >= 0; --i) {
int x = (i < this->size() ? (*this)[i] : 0);
int p = bit.lower_bound(x + 1);
ret.push_back(p);
bit.add(p, -1);
}
return ret;
}
};
void solve() {
int n;
cin >> n;
Factoradic L(n + 1);
Factoradic R(n + 1);
R[n] = 1;
L.shrink();
R.shrink();
while (1) {
auto mid = (L + R) / 2;
if (mid == L) break;
auto P = mid.to_permutation(n);
cout << "? ";
for (size_t i = 0; i < P.size(); ++i) {
cout << P[i] + 1;
if (i != P.size() - 1) cout << " ";
}
cout << endl;
int res;
cin >> res;
if (res == 0) {
R = mid;
} else {
L = mid;
}
}
auto P = L.to_permutation(n);
cout << "! ";
for (size_t i = 0; i < P.size(); ++i) {
cout << P[i] + 1;
if (i != P.size() - 1) cout << " ";
}
cout << endl;
}
int main() {
// cin.tie(0)->sync_with_stdio(0);
// cout << fixed << setprecision(12);
int t;
t = 1;
// cin >> t;
while (t--) solve();
return 0;
}