题目描述

有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的。然
后两人轮流进行操作。每次操作选择一个白色的格子,假设它的下标为x。接着,选择一个大小在1~n/x之间的整数
k,然后将下标为x、2x、...、kx的格子都进行颜色翻转。不能操作的人输。现在甲(先手)有一些询问。每次他
会给你一个数组的初始状态,你要求出对于这种初始状态他是否有必胜策略。
 

输入格式

接下来2*K行,每两行表示一次询问。在这两行中,第一行一个正整数W,表示数组中有多少个格子是白色的,第二
行则有W个1~N之间的正整数,表示白色格子的对应下标。

输出格式

对于每个询问,若先手必胜输出"Yes",否则输出"No"。答案之间用换行隔开


数据范围

N<=1000000000 , K,W<=100 , 不会有格子在同
一次询问中多次出现。

  • 题解

    • 可以发现变颜色这类问题是符合分解理论的,求出所有位置的sg值异或得到游戏的sg值;
    • 考虑所有位置的sg值如何求;
    • 可以写出一个$O(n^2)$的暴力(注意终止状态的$sg$为0);
    • 考虑改进暴力,打表发现对于一个$n$的所有$i$,$\frac{n}{i}$相同的位置sg值也相同;
    • 将$n$下底分块,就只需要求出$\sqrt{n}$个块的sg函数;
    • 由于是异或,只需要判断在某个块里的奇偶性就可以知道经过这个块的异或值;
    • 同时sg值由于是$mex$所以没有很大,$i<=sqrt(n)$的直接存,$i>sqrt{n}$的存在$\frac{n}{i}$里面:
    • 时间复杂度:$O(n)$ ?, 空间复杂度:$O(\sqrt{n})$;
 #include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int n,m,u,a[N],b[N],tot,vis[N],q[N];
void pre(){
for(int i=tot,tmp;i;--i){
tmp=;
int x = q[i];
for(int j=x*,lst;j<=n;j=lst+x){
lst=n/(n/j)/x*x;
int t=lst<=u?a[lst]:b[n/lst];
vis[tmp^t]=i;
if(((lst-j)/x+)&)tmp^=t;
}
for(int j=;;++j)if(vis[j]!=i){tmp=j;break;}
if(x<=u)a[x]=tmp;else b[n/x]=tmp;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("bzoj4035.in","r",stdin);
freopen("bzoj4035.out","w",stdout);
#endif
scanf("%d%d",&n,&m);u=sqrt(n);
for(int i=,lst;i<=n;i=lst+){lst=n/(n/i);q[++tot]=lst;}
pre();
for(int i=,x,tmp;i<=m;++i){
scanf("%d",&x);tmp=;
for(int j=,y;j<=x;++j){
scanf("%d",&y);
y=n/(n/y);
tmp^= y<=u?a[y]:b[n/y];
}
puts(tmp?"Yes":"No");
}
return ;
}

bzoj4035

 #include<bits/stdc++.h>
using namespace std;
const int N=;
int n,vis[N],sg[N];
int main(){
// freopen("exp.in","r",stdin);
freopen("exp.out","w",stdout);
for(n=;n<=;++n){
for(int i=;i<=n;++i)sg[i]=;
for(int i=n;i;--i){
for(int j=;j<=n/i;++j)vis[j]=;
int tmp = ;
for(int j=i+i;j<=n;j+=i){
tmp ^= sg[j];
vis[tmp]=;
}
for(int j=;j<=n/i;j++)if(!vis[j]){sg[i]=j;break;}
}
//for(int i=1;i<=100-n+1;++i)putchar(' ');
//for(int i=1;i<=n;++i)putchar(' ');
for(int i=;i<=n;++i)printf("%d ",sg[i]);
//printf("%d ",sg[n-2]);
//for(int i=3;i<=n;i+=3)printf("%d ",sg[i]);
puts("");
}
/*
int now = 20, cnt=0;
for(int i=now,j;i;i=j,now>>=1){
j = i - ((now + 1)>>1);
for(int k=i;k>j;--k)printf("%d",sg[k]),cnt++;
puts("");
}
cout<<cnt<<endl;
*/
return ;
}

暴力

bzoj4035【HAOI2015】数组游戏的更多相关文章

  1. bzoj4035 [HAOI2015]数组游戏

    这题显然把每个白格子看成一个子游戏 一个白格子$x$的$sg$值是$mex{[0,sg[2x],sg[2x] XOR sg[3x].....]}$ 打表发现一个数的$sg$值只和$n/x$有关,然后分 ...

  2. 【BZOJ4035】数组游戏(博弈论)

    [BZOJ4035]数组游戏(博弈论) 题面 BZOJ 洛谷 题解 很明显是一个翻硬币游戏的变形,因此当前局面的\(SG\)函数值就是所有白格子单独存在的\(SG\)函数的异或和. 那么,对于每一个位 ...

  3. 【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)

    4035: [HAOI2015]数组游戏 Time Limit: 15 Sec  Memory Limit: 32 MBSubmit: 181  Solved: 89 Description 有一个长 ...

  4. @bzoj - 4035@ [HAOI2015]数组游戏

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏: 首先,数 ...

  5. [HAOI2015]数组游戏

    题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...

  6. 【LOJ】#2126. 「HAOI2015」数组游戏

    题解 简单分析一下就知道\(\lfloor \frac{N}{i} \rfloor\)相同的\(i\)的\(sg\)函数相同 所以我们只要算\(\sqrt{n}\)个\(sg\)函数就好 算每一个\( ...

  7. JZYZOJ1540 BZOJ4035 [ haoi2015 上午] T3 博弈论 sg函数 分块 haoi

    http://172.20.6.3/Problem_Show.asp?id=1540 之前莫比乌斯反演也写了一道这种找规律分块计算的题,没觉得这么恶心啊. 具体解释看代码. 翻硬币的具体方法就是分别算 ...

  8. 最浅谈的SG函数

    [更新] Nim游戏的经验: 每次最多取m个——%(m+1) 阶梯nim——奇数位无视,看偶数位互相独立,成一堆一堆的石子 . . . . 既然被征召去汇总算法..那么挑个简单点的SG函数好了.. 介 ...

  9. sg函数小结

    sg函数小结 sg函数是处理博弈问题的重要工具. 我们知道sg(x)=mex{sg(j)|x能到达状态j} sg(x)=0时代表后手赢,否则先手赢. 对于一个问题,如果某些子问题是相互独立的,我们就可 ...

随机推荐

  1. C++多态深入分析!

    以下分析是基于VS2010的.以后会使用G++分析看看G++如何处理多态! // polymorphic_test.cpp : 定义控制台应用程序的入口点. // /** 特别注意:实现C++多态,除 ...

  2. 导出excel失败,提示提示加载类型库/DDL出错

    首先,这里提供的解决办法仅适用于出现如下异常的情况:无法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“M ...

  3. Thunder-Final冲刺中间产物-2017秋-软件工程第十二次作业

    Thunder-Final发布中间产物(WBS&PSP) WBS: 分解方式:按照「爱阅」阅读器的实施过程分解 使用工具:visio 2013 PSP: PSP 预期时间 Planning 计 ...

  4. TeamWork#3,Week5,The First Meeting of Our Team

    sixsix第一次会议记录 [会议时间]2014年10月23日星期四19:00-20:00 [会议形式]小组讨论 [会议地点]5号公寓 [会议主持]高雅智 [会议记录]张志浩 会议整体流程 一.签到 ...

  5. Daily Scrum (2015/10/23)

    这天晚上PM和我一起细算下来这周的确做了不少事儿.由于这天是周五,有的组员今晚有外出活动,有的组员忙了一周想休息一下.所以PM与我讨论提出今晚就布置些阅读的任务,给组员们一些自由分配的时间: 成员 今 ...

  6. 软工实践-Beta 冲刺 (7/7)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...

  7. linshi18

    #include<iostream> using namespace std; int n,m,k; #define max 100 char mmap[max][max]; int mm ...

  8. java中static使用之静态方法注意点

    1.静态方法可以直接调用同类中的静态成员,但是不能直接调用非静态成员,这是为什么呢?大家想一下,静态成员在对象创建之前就要写入内存,所以它在内存中是实实在在的存在的,而非静态还不存在内存中,所以不能调 ...

  9. Sprint2-2.0

    1.开始一个新的冲刺: 起止:2016.6.1~2016.6.14 按照以下过程进行 ProductBacklog:继续向下细化 Sprint 计划会议:确定此次冲刺要完成的目标 Sprint Bac ...

  10. 简单复利计算java板

    一.要求: 1.客户说:帮我开发一个复利计算软件. 2如果按照单利计算,本息又是多少呢? 3.假如30年之后要筹措到300万元的养老金,平均的年回报率是3%,那么,现在必须投入的本金是多少呢? 4.利 ...