• luoguP3235 [HNOI2014]江南乐 数论分块 + 博弈论



    感觉其实很水?

    题目就是一个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;
    }
    
  • 相关阅读:
    构造方法
    linux操作系统基础篇(四)
    linux操作系统基础篇(三)
    linux操作系统基础篇(二)
    linux操作系统基础篇(一)
    计算机网络基础
    计算机操作系统
    计算机基础!
    Open vSwitch intro
    Less(11)
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10152706.html
Copyright © 2020-2023  润新知