SG函数
来源:互联网 发布:apm源码分析位置控制 编辑:程序博客网 时间:2024/05/07 08:36
参考:
http://www.cnblogs.com/frog112111/p/3199780.html
http://cyan.logdown.com/posts/286252-combinatorial-games-with-the-sg-function
hdu 1848
bzoj 1188
bzoj 3576
SG SG?SG SG!
hdu 1848
直接求
const int maxn = 16, size = 1000;int fb[maxn + 5] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987}, sg[size + 5];void prework(){ static bool hash[size + 5]; memset(hash, false, sizeof(hash)); for(int i = 1; i <= size; i++) { for(int j = 1; j < maxn && fb[j] <= i; j++) hash[sg[i - fb[j]]] = true; for(int j = 0; j <= i; j++) if(!hash[j]) {sg[i] = j; break;} for(int j = 1; j < maxn && fb[j] <= i; j++) hash[sg[i - fb[j]]] = false; }}int main(){ int m, n, q;#ifndef ONLINE_JUDGE freopen("1848.in","r",stdin); freopen("1848.out","w",stdout);#endif prework(); read(m), read(n), read(q); do { puts((sg[m]^sg[n]^sg[q]) ? "Fibo" : "Nacci"); read(m), read(n), read(q); }while(m + n + q);#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0;}
bzoj 1188
考虑在一个位置的瓶子,
按每个瓶子中的巧克力豆个数的奇偶性分类,
巧克力豆个数为奇数时的
巧克力豆个数为偶数时时
然后求模拟玩法求每个位置巧克力豆个数为奇数时
如何确定游戏先手能否获胜?
设ans 为巧克力豆个数为奇数的位置的sg 函数值的异或和。
如果ans>0 ,那么 先手有必胜策略。如何输出第一步的操作?
我们希望后继状态的sg 值为0 ,那么当ans⊕sg(i)⊕sg(j)⊕sg(k)=0(i<j≤k) 时,
对i ,j ,k 三个瓶子操作可以保证先手必胜。
const int maxn = 30;int n, sg[maxn], a[maxn];int hash[maxn*maxn];void prework(int size){ for(int i = 1; i <= size; i++) { for(int j = 1; j < i; j++) for(int k = 1; k <= j; k++) hash[sg[j] ^ sg[k]] = i; for(int j = 0; j <= i*i; j++) if(hash[j] != i) { sg[i] = j; break; } }}void init(){ read(n); for(int i = 1; i <= n; i++) read(a[i]);}void solve(){ int s1 = 0, s2 = 0, s3 = 0; int ans = 0, cnt = 0; for(int i = 1; i <= n; i++) if(a[i]&1) ans ^= sg[n - i + 1]; if(!ans) {puts("-1 -1 -1"), puts("0"); return;} for(int i = 1; i <= n; i++) for(int j = i + 1; j <= n; j++) for(int k = j; k <= n; k++) if(!(ans ^ sg[n - i + 1] ^ sg[n - j + 1] ^ sg[n - k + 1])) if(!cnt++) s1 = i, s2 = j, s3 = k; write(s1 - 1), putchar(' '); write(s2 - 1), putchar(' '); write(s3 - 1), puts(""); write(cnt), puts(""); }int main(){ int T;#ifndef ONLINE_JUDGE freopen("1188.in","r",stdin); freopen("1188.out","w",stdout);#endif read(T), prework(maxn - 5); while(T--) init(), solve(); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0; }
bzoj 3576
这道题稍难一些。
设石子序列为
如果把
考虑
证明:
当
p<x√ 时,显然⌊x/p⌋ 最多只有x√ 个取值当
p≥x√ 时 ,x/p≤m ,注意到⌊x/p⌋ 是整数,所以最多也只有x√ 个取值
做数学题时的常用优化方法。。。
而
另外我们还发现
时间复杂度:
const int maxs = 1e5 + 50, size = maxs<<1, maxn = 110;int T, f;int n, a[maxn];#define work(t, c) (sg(((t) / (c) + 1)*((t) % (c) &1))^sg((t) / (c)*((c) - (t) % (c) &1)))int sg(int x){ static bool flag[maxs] = {false}; static int hash[size] = {0}, _sg[maxs]; if(x < f) return 0; if(flag[x]) return _sg[x]; flag[x] = true; for(int i = 2; i <= x; i = x/(x/i) + 1) { hash[work(x, i)] = x; if(i < x) hash[work(x, i + 1)] = x; } int pos = 0; while(hash[pos] == x) pos++; return (_sg[x] = pos);}int solve(){ int ans = 0; read(n); for(int i = 1; i <= n; i++) read(a[i]), ans ^= sg(a[i]); return ans; }int main(){#ifndef ONLINE_JUDGE freopen("3576.in","r",stdin); freopen("3576.out","w",stdout);#endif read(T), read(f); while(T--) putchar('0' + (solve()?1:0)), putchar(T?' ':'\n');#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0; }
- sg函数
- SG函数
- SG函数
- SG函数
- SG函数
- SG函数
- SG函数
- SG函数
- SG函数
- SG函数
- sg函数
- SG函数
- SG函数
- SG函数
- sg函数
- SG函数
- SG函数
- SG函数
- c/c++ static 对象
- AFNetworking2.0源码解析
- poj2386C语言解题报告
- 记录帖:Textview在android代码中可以动态的设置字号单位
- [Leetcode] Valid Parentheses
- SG函数
- 编写软件测试用例需要注意哪些
- poj-2888 Magic Bracelet
- 快速排序(qsort and sort)
- HDU 1069 – Monkey and Banana
- 什么才算是真正的编程能力?
- 【system】VMware虚拟机 CentOS 6.6系统安装配置详细图文教程
- I学霸官方免费教程三十三:Java集合框架之Map集合
- c++ 操作 xlsx