luoguP3235 [HNOI2014]江南樂 數論分塊 + 博弈論
阿新 • • 發佈:2018-12-20
感覺其實很水?
題目就是一個Multi SG遊戲,只需要預處理出所有的\(sg\)值即可\(O(Tn)\)計算
對於計算\(sg[n]\)而言,顯然我們可以列舉劃分了\(x\)堆來檢視後繼狀態
那麼,有\(n\;mod\;x\)個\(\left \lfloor \frac{n}{x} \right \rfloor + 1\)的堆以及\(x - n\;mod\;x\)個\(\left \lfloor \frac{n}{x} \right \rfloor\)的堆
暴力轉移就是\(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; }