[gym 101149 M. Ex Machina]構造+線段樹
分類:Data Structure
SegMent Tree
Construction
1. 題目鏈接
[gym 101149 M. Ex Machina]構造+線段樹
2. 題意描述
交互題。有
3. 解題思路
比較有意思的一道構造題。題目要求用
按照線段樹來比較大小,用節點記錄,子樹的最大值所在的位置。葉子節點有
然後,根據求出的最大數所在位置,求出了從根節點到該葉子節點的一條路徑,這個路徑上最多
4. 實現代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lb;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> puu;
typedef pair<lb, lb> pbb;
typedef vector<int> vi;
typedef tuple<int, int, int> iii;
const int INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
template<typename T> inline void umax(T &a, T b) { a = max(a, b); }
template<typename T> inline void umin(T &a, T b) { a = min(a, b); }
template<typename T> inline T randIntv(const T& a, const T& b) { return (T)rand() % (b - a + 1) + a; }
void debug() { cout << endl; }
template<typename T, typename ...R> void debug (T f, R ...r) { cout << "[" << f << "]"; debug (r...); }
const int MAXN = 1005;
int n, seg[MAXN << 2];
namespace Interaction {
int times;
#ifdef ___LOCAL_WONZY___
int rank[MAXN];
#endif
void init() {
times = n + 24;
#ifdef ___LOCAL_WONZY___
for (int i = 1; i <= n; ++i) rank[i] = i;
random_shuffle(rank + 1, rank + n + 1);
for (int i = 1; i <= n; ++i) printf("[%d]", rank[i]);
printf("\n");
#endif
}
#ifdef ___LOCAL_WONZY___
int ask(int a, int b) {
-- times;
if (rank[a] == rank[b]) return 0;
return (rank[a] < rank[b]) ? -1 : 1;
}
#else
char buf[10];
int ask(int a, int b) {
-- times;
printf("? %d %d\n", a, b);
fflush(stdout);
scanf("%s", buf);
if (buf[0] == '=') return 0;
return (buf[0] == '<') ? -1 : 1;
}
#endif // ___LOCAL_WONZY___
}
#define lch (rt << 1)
#define rch (rt << 1 | 1)
#define lson l, md, lch
#define rson md + 1, r, rch
int idx[MAXN], tot;
void build(int l, int r, int rt) {
if (l == r) {
seg[rt] = idx[l];
return;
}
int md = (l + r) >> 1;
build(lson);
build(rson);
int a = seg[lch], b = seg[rch];
int ret = Interaction::ask(a, b);
assert(ret != 0);
seg[rt] = ret == 1 ? a : b;
}
void dfs(int l, int r, int rt) {
if (l == r) return;
int md = (l + r) >> 1;
if (seg[rt] == seg[lch]) {
idx[++ tot] = seg[rch];
dfs(lson);
} else {
idx[++ tot] = seg[lch];
dfs(rson);
}
}
int main() {
#ifdef ___LOCAL_WONZY___
freopen("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
scanf("%d", &n);
Interaction::init();
for (int i = 1; i <= n; ++i) idx[i] = i;
build(1, n, 1);
// debug(seg[1]);
tot = 0;
dfs(1, n, 1);
build(1, tot, 1);
// debug(seg[1]);
printf("! %d\n", seg[1]);
assert(Interaction::times > 0);
#ifdef ___LOCAL_WONZY___
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << "ms." << endl;
#endif // ___LOCAL_WONZY___
return 0;
}