bzoj4035 [HAOI2015]数组游戏

这题显然把每个白格子看成一个子游戏

一个白格子$x$的$sg$值是$mex{[0,sg[2x],sg[2x] XOR sg[3x].....]}$

打表发现一个数的$sg$值只和$n/x$有关,然后分块乱搞就行了。

一开始开了个$map$,一直$TLE$,换成两个数组就过了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <map>
 7 #include <ctime>
 8 #define N 100050
 9 using namespace std;
10 bool bo[257];
11 int n,m,T,sg1[N],sg2[N];
12 int getsg(int x){
13     int now=0;
14     memset(bo,0,sizeof bo);
15     int y=n/x;
16     for(int i=2,j;i<=y;i=j+1){
17         j=y/(y/i);
18         int sg=(i*x>m)?sg1[n/(i*x)]:sg2[i*x];
19         if((j-i+1)&1)now^=sg;
20         bo[now^sg]=1;bo[now]=1;
21     }
22     for(int i=1;;i++)if(!bo[i])return i;
23 }
24 int tot;
25 int main(){
26     scanf("%d",&n);
27     m=sqrt(n);
28     for(int i=n,j;i;i=j-1){
29         j=n/((n/i)+1)+1;
30         if(i>m)sg1[n/i]=getsg(i);
31         else sg2[i]=getsg(i);
32     }
33     scanf("%d",&T);
34     int num,ans;
35     while(T--){
36         scanf("%d",&num);ans=0;
37         for(int i=1,x;i<=num;i++){
38             scanf("%d",&x);
39             x=(x>m)?sg1[n/x]:sg2[x];
40             ans^=x;
41         }
42         if(ans)puts("Yes");
43         else puts("No");
44     }
45     return 0;
46 }
View Code
原文地址:https://www.cnblogs.com/Ren-Ivan/p/8333828.html