Loading

[AGC064C] Erase and Divide Game

link

感觉题解说的都很不清晰,这里只谈个人理解。

考虑操作的本质是什么,两人从低到高确定二进制下的每一位填的数,并且场上只保留对应后缀的数字,当场上没有数字时当前操作者输。

\(f[i,S]\) 表示确定了前 \(i\) 位,填的数为 \(S\),接下来先手是否能赢,那么有 \(f[i, S] = \neg (f[i + 1, S] \land f[i + 1, S + 2^i])\)。特别的,当不存在数字时,\(f[i, S] = -1\),且如果两个儿子中有一个为 \(-1\),那么 \(f[i, S] = 1\)

考虑枚举 \(i = 59...0\),直觉告诉我们,\(f[i,\_]\) 的连续段数为 \(O(n)\)

对于每个 \(i\),我们显然可以将 \(f[i + 1, 0...2^i - 1]\)\(f[i + 1, 2^i ... 2^{i + 1} - 1]\) 通过双指针的方式合并起来。考虑数学归纳法,若 \(i + 1\) 层连续段数为 \(O(n)\),由双指针可得第 \(i\) 层连续段数也是 \(O(n)\)

时间复杂度 \(O(n\log V)\)

  • 启示:不要认为极其暴力的 dp 不可行,世上有数百万种 dp 优化的方式。
点击查看代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define pir pair <ll, ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn = 1e6 + 10, P = 60;
ll t, n, pos[maxn], val[maxn], m, _pos[maxn], _val[maxn], _m;
ll l[maxn], r[maxn];
int main() {
	scanf("%lld", &t);
	while(t--) {
		scanf("%lld", &n); m = 0, r[0] = -1;
		for(ll i = 1; i <= n; i++) {
			scanf("%lld%lld", l + i, r + i);
			if(l[i] > r[i - 1] + 1) {
				pos[++m] = r[i - 1] + 1;
				val[m] = -1;
			}
			pos[++m] = l[i];
			val[m] = 1;
		}
		if(r[n] < (1ll << P) - 1)
			pos[++m] = r[n] + 1, val[m] = -1;
		for(ll i = P - 1; ~i; i--) {
			ll x = 1, B = 1ll << i;
			while(x <= m && pos[x] < B) ++x;
			if(x > m || pos[x] > B) {
				for(ll j = m; j >= x; j--)
					pos[j + 1] = pos[j], val[j + 1] = val[j];
				pos[x] = (1ll << i), val[x] = val[x - 1], ++m;
			}
			pos[m + 1] = (1ll << i + 1), _m = 0;
			for(ll j = 1, k = x; j < x; j++) {
				while(pos[k + 1] - B <= pos[j]) ++k;
				while(pos[k] - B < pos[j + 1]) {
					_pos[++_m] = max(pos[j], pos[k] - B);
					if(min(val[j], val[k]) == -1) {
						if(val[j] + val[k] == -2)
							_val[_m] = -1;
						else _val[_m] = 1;
					} else {
						_val[_m] = (val[j] & val[k]) ^ 1;
					} ++k;
				} if(k > x) --k;
			}
			for(ll i = 1; i <= _m; i++)
				pos[i] = _pos[i], val[i] = _val[i];
			m = _m;
		} puts(val[1]? "Takahashi" : "Aoki");
	}
	return 0;
}
posted @ 2024-08-16 15:25  Lgx_Q  阅读(10)  评论(0编辑  收藏  举报