「CF 1483E」Vabank(交互,构造)

题目链接

题意:

你要猜出一个整数 (M)(0 le M le 10^{14}))。一开始,你有 (1) 元钱。每次,你可以询问一个整数 (X),接下来:

  • (X le M),你会获得 (X) 元钱;
  • (X > M),你会损失 (X) 元钱;
  • 你能知道是 (X le M) 还是 (X > M)

任何时刻,你要保证你的存款非负。你要在 (105) 次询问内问出 (M)

思路:

维护当前 (M) 所在的区间 ([L, R)),每询问一次就对这个区间进行收缩。

(L) 足够大时,只要询问 (L) 就能白嫖 (L) 元。所以我们先要把 (L, R) 变为同一级别。只要依次询问 (1, 2, 4, 8, ldots) 即可。

发现当 (L, R) 同级时,询问的 (X) 也与它们同级。因此只要有一定的本金,一次收益和一次损失可以看作抵消。

更好的解释是,一次收益和一次损失总共最多亏损 (R - L) 元,而随着询问次数增多 (R - L) 指数级减少,所以 (sum R - L)(O(M)) 的。

所以,我们设计 (f_{i, j}) 表示用 (i) 次询问,当前还能损失 (j) 次时能问出的最大区间长度。那么有转移:

  • (f_{i, j} = f_{i - 1, j - 1} + f_{i - 1, j + 1} (j > 0))
  • (f_{i, 0} = f_{i - 1, 1})

按照转移式进行询问即可。

代码:

#include <bits/stdc++.h>

#define rep(i, a, b) for (int i = (a); i <= int(b); i++)
#define per(i, a, b) for (int i = (a); i >= int(b); i--)

using namespace std;

typedef long long ll;

int T;

bool ask(ll x) {
	printf("? %lld
", x);
	fflush(stdout);
	char s[10];
	scanf("%s", s);
	return s[0] == 'L' ? 1 : 0;
}

void putans(ll m) {
	printf("! %lld
", m);
	fflush(stdout);
}

ll dp[70][70];

void init(int n) {
	rep(i, 0, n) {
		dp[0][i] = 1;
	}
	rep(i, 1, n) {
		dp[i][0] = dp[i - 1][1];
		rep(j, 1, n - i) {
			dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1];
		}
	}
}

ll get(int a, int b, ll l, ll r) {
	if (r - l == 1) {
		return l;
	}
	if (b == 0) {
		ask(l);
		return get(a - 1, 1, l, r);
	}
	ll c = min(dp[a - 1][b - 1], r - l - 1);
	if (!ask(l + c)) {
		return get(a - 1, b - 1, l, l + c);
	} else {
		return get(a - 1, b + 1, l + c, r);
	}
}

void work() {
	if (!ask(1)) {
		return putans(0);
	}
	ll l = 0, r = 0;
	rep(i, 1, 46) {
		if (!ask(1ll << i)) {
			l = 1ll << (i - 1);
			r = 1ll << i;
			break;
		}
	}
	if (!l) {
		l = 1ll << 46;
		r = ll(1e14) + 1;
	}
	int k = 0;
	rep(i, 0, 59) {
		if (dp[i][1] >= r - l) {
			k = i;
			break;
		}
	}
	rep(i, 1, 6) {
		ask(l);
	}
	ll ans = get(k, 1, l, r);
	putans(ans);
}

int main() {
	init(60);
	scanf("%d", &T);
	while (T --> 0) {
		work();
	}
	return 0;
}

评价:

思维难度:5/10

代码难度:3/10

评分:3/10

原文地址:https://www.cnblogs.com/Alfalfa-w/p/14731709.html