感觉其实很水?
题目就是一个Multi SG游戏,只需要预处理出所有的(sg)值即可(O(Tn))计算
对于计算(sg[n])而言,显然我们可以枚举划分了(x)堆来查看后继状态
那么,有(n;mod;x)个(left lfloor frac{n}{x} ight floor + 1)的堆以及(x - n;mod;x)个(left lfloor frac{n}{x} ight floor)的堆
暴力转移就是(O(10^{10}))的
显然上面可以数论分块,再讨论一下奇偶即可
复杂度(O(10^5 sqrt 10^5))
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)
const int sid = 2e5 + 5;
int T, F, tim;
int sg[sid], mex[sid];
inline void init() {
rep(i, F, 100000) {
++ tim;
for(ri ii = 2, jj; ii <= i; ii = jj + 1) {
jj = i / (i / ii);
int p = i / ii, S = i - p * ii, S2 = ii - S, SG = 0;
if(S & 1) SG ^= sg[p + 1];
if(S2 & 1) SG ^= sg[p]; mex[SG] = tim;
if(ii + 1 > jj) continue;
S = i - p * (ii + 1); S2 = (ii + 1) - S; SG = 0;
if(S & 1) SG ^= sg[p + 1];
if(S2 & 1) SG ^= sg[p]; mex[SG] = tim;
}
rep(j, 0, 100000) if(mex[j] != tim)
{ sg[i] = j; break; }
}
}
int main() {
cin >> T >> F;
init();
while(T --) {
int n, x, SG = 0;
cin >> n;
rep(i, 1, n) { cin >> x; SG ^= sg[x]; }
printf("%d ", SG ? 1 : 0);
}
return 0;
}