Aladdin and the Game of Bracelets LightOJ - 1344 博弈论,求sg函数

  • 这道题显然就是要求每一个珠子串对应的 S G SG SG
  • 假设选取该珠子串中的一个权重 w w w ,拆分成1个或多个字串后,将这些子串的 S G SG SG 值的异或和,便是该珠子串到下一个状态的可达 S G SG SG 值标记。
  • 当最后子串里仅剩下一个珠子的时候,这个的子串 S G SG SG 值为1
  • 每次都递归的求出子串的 S G SG SG 值,最后按照 S G SG SG 的含义取 m e x mex mex 即可
  • 详情请看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uii;
typedef pair<int, ll> pii;
template<typename T>
inline void rd(T& x)
{
    
    
	int tmp = 1; char c = getchar(); x = 0;
	while (c > '9' || c < '0') {
    
     if (c == '-')tmp = -1; c = getchar(); }
	while (c >= '0' && c <= '9') {
    
     x = x * 10 + c - '0'; c = getchar(); }
	x *= tmp;
}
const int N = 2e5 + 10;
const int M = 1e7 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m, id;
int a[N];
int sg[55][55][55];
int b[55][55];
int solve(int l, int r);
int dfs(int x, int l, int r) {
    
     //选取一个权重进行切割子串。
	int ans = 0;
	int posl = -1;
	for (int i = l; i <= r; ++i) {
    
    
		if (a[i] >= x && posl != -1) {
    
    
			ans ^= solve(posl, i - 1);
			posl = -1;
		}
		else if (a[i] < x && posl == -1) posl = i;
	}
	if (posl != -1) ans ^= solve(posl, r);
	return ans;
}
int solve(int l, int r) {
    
      //求[l,r]这个串的sg值
	if (~sg[id][l][r]) return sg[id][l][r];
	if (l == r) return sg[id][l][r] = 1;
	bool vis[128] = {
    
     false };
	for (int i = l; i <= r; ++i) {
    
    
		vis[dfs(a[i], l, r)] = true;
	}
	for (int i = 0;; ++i) {
    
    
		if (!vis[i]) {
    
    
			return sg[id][l][r] = i;
		}
	}
}
int main() {
    
    
#ifdef _DEBUG
	FILE* _INPUT = freopen("input.txt", "r", stdin);
	//	FILE* _OUTPUT = freopen("output.txt", "w", stdout);
#endif // !_DEBUG
	int cas = 0, T = 0;
	rd(T);
	while (T--) {
    
    
		//	while (~scanf("%d %d", &n,&k)) {
    
    
		rd(m);
		int ans = 0;
		memset(sg, -1, sizeof(sg));
		for (int ii = 1; ii <= m; ++ii) {
    
    
			rd(n); b[ii][0] = n;
			for (int i = 1; i <= n; ++i) rd(a[i]);
			for (int i = 1; i <= n; ++i) b[ii][i] = a[i];
			id = ii;
			ans ^= solve(1, n);
		}
		printf("Case %d: ", ++cas);
		if (ans) {
    
    
			puts("Aladdin");
			vector<pii>res;
			for (int ii = 1; ii <= m; ++ii) {
    
    
				n = b[ii][0];
				unordered_map<int, bool>visn;
				for (int i = 1; i <= n; ++i) a[i] = b[ii][i];
				for (int i = 1; i <= n; ++i) {
    
    
					if (!visn[b[ii][i]]) {
    
    
						visn[b[ii][i]] = true;
						id = ii;
						if ((ans ^ sg[ii][1][n] ^ dfs(b[ii][i], 1, n)) == 0) {
    
    
							res.push_back({
    
     ii,b[ii][i] });
						}
					}
				}
			}
			sort(res.begin(), res.end(), [](const pii& a, const pii& b) {
    
    
				return a.first < b.first || a.first == b.first && a.second < b.second;
				});
			for (auto v : res) printf("(%d %d)", v.first, v.second);
			puts("");
		}
		else puts("Genie");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bloom_er/article/details/113776228