• 洛谷 P3235 [HNOI2014]江南乐 解题报告


    P3235 [HNOI2014]江南乐

    Description

    两人进行 T 轮游戏,给定参数 F ,每轮给出 N 堆石子,先手和后手轮流选择石子数大于等于 F 的一堆,将其分成任意(大于1)堆,使得这些堆中石子数最多的和最少的相差不超过1(即尽量均分)。求先手和后手谁必胜。

    Input

    输入第一行包含两个正整数T和F,分别表示游戏组数与给定的数。
    接下来T行,每行第一个数N表示该组游戏初始状态下有多少堆石子。之后N个正整数,表示这N堆石子分别有多少个。

    Output

    输出一行,包含T个用空格隔开的0或1的数,其中0代表此时小A(后手)会胜利,而1代表小A的对手(先手)会胜利。


    预处理每个单一游戏的(SG)

    小于(F)的置(0)必败

    大于(F)的枚举拆分的堆数,把分开的用(SG)定理求一个异或和。

    发现可以用乘除分块优化,对奇偶性相同的堆数当(lfloorfrac{n}{l} floor)一样时,答案一样。

    预处理的复杂度(O(nsqrt n))

    注意特判(SG_1=0)

    直接(SG)定理回答询问就可以了。


    Code:

    #include <cstdio>
    const int N=1e5+1;
    int SG[N],T,F,n,is[N];
    int hxor(int x,int k)
    {
        if(k&1) return x;
        return 0;
    }
    int main()
    {
        scanf("%d%d",&T,&F);
        for(int i=F;i<N;i++)
        {
            for(int l=1,r;l<=i;l=r+1)
            {
                r=i/(i/l);
                is[hxor(SG[i/l],l-i%l)^hxor(SG[i/l+1],i%l)]=i;
                ++l;
                if(l<=r&&l<=i) is[hxor(SG[i/l],l-i%l)^hxor(SG[i/l+1],i%l)]=i;
            }
            for(int j=0;is[j]==i;j++) SG[i]=j+1;
        }
        SG[1]=0;
        while(T--)
        {
            scanf("%d",&n);
            int sg=0;
            for(int x,i=1;i<=n;i++) scanf("%d",&x),sg^=SG[x];
            printf("%d ",sg>0);
        }
        return 0;
    }
    

    2018.12.19

  • 相关阅读:
    prometheus监控示例
    es索引管理工具-curator
    GlusterFS分布式文件系统的使用
    Django的admin相关
    Django的form表单
    Django-models & QuerySet API
    python-css基础知识
    PXC 避免加入集群时发生SST
    ERROR 1682 (HY000)
    pxc群集搭建
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10141388.html
Copyright © 2020-2023  润新知