【BZOJ4035】数组游戏,博弈论+分块乱搞
2017-03-14 09:22
417 查看
传送门
思路:
起初思路挺好,后来就比较奇怪的一道题目
玩法很像SDOI2016R2的硬币游戏,不过那个题目直接暴力SG就可以过,本题直接套规则只有30分;
稍微优化一下,不枚举k,直接每次xor一下后继状态的sg,可以得50分,复杂度O(nlogn);
70分需要一个比较好玩的结论:
如果⌊ni⌋=⌊nj⌋,那么sg(i)=sg(j)
我们可以归纳证明一下:
当⌊ni⌋=1时,显然sg(i)=1,因为它只能令自身反色
当⌊ni⌋>1时,sg(i)由⌊n2i⌋,⌊n3i⌋..的sg值决定,又⌊nij⌋=⌊⌊ni⌋j⌋,所以⌊ni⌋相同的位置后继状态相同,sg值也就相同了
然后就可以分块求了,⌊ni⌋的取值最多有2n√种,转移时考虑落在当前区间内的后继点奇偶就可以了,复杂度O(n),可以得70分,个人以为这正是本题巧妙的地方
接下来的优化就比较玄学了,本人一开始并不知道怎么做,弃疗后百度了题解,好像是什么跑不满的小常数O(n),还有什么玄学/hash,表示不是很懂,不过里面所说的合并sg给了我启发,因为有很多⌊ni⌋不相等的块sg值相同,这个优化比较奇怪但确实很好用,在n=109时用这个优化,块的数量只有9223个,所以我们只要求出一个块的sg后和前一个块比较,如果sg相同就合并,查找时二分一下就可以了
提示:本题中sg函数都不大
代码:
思路:
起初思路挺好,后来就比较奇怪的一道题目
玩法很像SDOI2016R2的硬币游戏,不过那个题目直接暴力SG就可以过,本题直接套规则只有30分;
稍微优化一下,不枚举k,直接每次xor一下后继状态的sg,可以得50分,复杂度O(nlogn);
70分需要一个比较好玩的结论:
如果⌊ni⌋=⌊nj⌋,那么sg(i)=sg(j)
我们可以归纳证明一下:
当⌊ni⌋=1时,显然sg(i)=1,因为它只能令自身反色
当⌊ni⌋>1时,sg(i)由⌊n2i⌋,⌊n3i⌋..的sg值决定,又⌊nij⌋=⌊⌊ni⌋j⌋,所以⌊ni⌋相同的位置后继状态相同,sg值也就相同了
然后就可以分块求了,⌊ni⌋的取值最多有2n√种,转移时考虑落在当前区间内的后继点奇偶就可以了,复杂度O(n),可以得70分,个人以为这正是本题巧妙的地方
接下来的优化就比较玄学了,本人一开始并不知道怎么做,弃疗后百度了题解,好像是什么跑不满的小常数O(n),还有什么玄学/hash,表示不是很懂,不过里面所说的合并sg给了我启发,因为有很多⌊ni⌋不相等的块sg值相同,这个优化比较奇怪但确实很好用,在n=109时用这个优化,块的数量只有9223个,所以我们只要求出一个块的sg后和前一个块比较,如果sg相同就合并,查找时二分一下就可以了
提示:本题中sg函数都不大
代码:
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; int n,m,q,cnt; int pos[64005],f[64005]; struct node{ int l,r,sg; }da[64005]; bool vis[1000]; void dp() { for (int i=pos[0];i;--i) { int t=0,mx=0,p=cnt; for (int last=2,j=2;j<=n/pos[i];j=last+1) { for (;j*pos[i]>da[p].r&&p;--p); if (p) last=da[p].r/pos[i]; vis[t^da[p].sg]=1; mx=max(mx,t^da[p].sg); if (last-j+1&1) t^=da[p].sg; vis[t]=1,mx=max(mx,t); } for (int j=1;;++j) if (!vis[j]) { f[i]=da[++cnt].sg=j; if (cnt>1&&da[cnt].sg==da[cnt-1].sg) da[--cnt].l=pos[i-1]+1; else da[cnt].l=pos[i-1]+1,da[cnt].r=pos[i]; break; } for (int j=0;j<=mx;++j) vis[j]=0; } } main() { scanf("%d%d",&n,&q); for (int last,i=1;i<=n;i=last+1) pos[++pos[0]]=last=n/(n/i); dp(); for (int x,ans;q;--q) { ans=0; scanf("%d",&m); for (;m;--m) scanf("%d",&x), ans^=f[lower_bound(pos+1,pos+pos[0]+1,n/(n/x))-pos]; puts(ans?"Yes":"No"); } }
相关文章推荐
- [SG函数 + 分块] BZOJ4035: [HAOI2015]数组游戏
- 【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)
- BZOJ 4035 [HAOI2015]数组游戏
- [bzoj4035]数组游戏
- bzoj4035 [HAOI2015]数组游戏
- 【博弈论】【SG函数】bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏
- BZOJ 4216 Pig 分块乱搞
- [BZOJ 1874] [BeiJing2009 WinterCamp] 取石子游戏 【博弈论 | SG函数】
- [BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】
- BZOJ 1022 SHOI2008 小约翰的游戏John 博弈论
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
- [BZOJ1188][HNOI2007]分裂游戏(博弈论)
- BZOJ 2141 排队 分块+树状数组
- BZOJ 1022 SHOI2008 小约翰的游戏John 博弈论
- BZOJ 3289: Mato的文件管理|分块|树状数组
- Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
- 【bzoj1022】【SHOI2008】【小约翰的游戏John】【博弈论】
- 【分块】【树状数组】bzoj3787 Gty的文艺妹子序列
- BZOJ1115:[POI2009]石子游戏Kam(博弈论)
- 【博弈论】【SG函数】【枚举】bzoj1188 [HNOI2007]分裂游戏