首页 > 其他 > 详细

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

时间:2018-01-23 12:33:12      阅读:196      评论:0      收藏:0      [点我收藏+]

http://172.20.6.3/Problem_Show.asp?id=1540

之前莫比乌斯反演也写了一道这种找规律分块计算的题,没觉得这么恶心啊。

具体解释看代码。

翻硬币的具体方法就是分别算出每个单个正面朝上的情况的sg函数然后异或。

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<map>
 7 #include<ctime>
 8 using namespace std;
 9 int n,k,w,mx;
10 int f[100010][2]={};//n/x和n/(n/x)代表的x的sg值,分成两部分使得储存需要的空间开根
11 //值得注意的是,这两种划分方式分出的x的范围是一定的,大概是数字的性质。
12 int vis[100010]={};
13 int doit(int x,int y){return x==y?x+1:y/(y/(x+1));}
14 int main(){
15     scanf("%d%d",&n,&k);
16     //暴力代码
17     /*for(int i=n;i>=1;i--){
18         int now=0;
19         for(int j=i+i;j<=n;j+=i){
20             now^=f[j];vis[now]=i;
21         }
22         for(int j=1;;j++){
23             if(vis[j]!=i){
24                 f[i]=j;
25                 break;
26             }
27         }
28     }*/
29     /*暴力打表后可以发现这个东西满足规律:
30         只要n/x(向下取整)相等sg值就相等。
31         于是就开始了漫长艰辛的分块计算之旅  
32         倒数真有趣
33          _
34         | |
35         | |
36      _ _| |_ _
37     | | | | | |
38     \_________/
39     */
40     mx=(int)sqrt(double(n));
41     for(int i=1;i<=n;i=doit(i,n)){//这里枚举的i从小到大,其实是n/x
42         int y,now=0,z;
43         for(int j=2;j<=i;j=doit(j,i)){//上一层枚举了n/x,这一层用同样的方式枚举他的倍数
44             y=i/j;//既然用n/x表达,扩大j倍自然是/j。
45             z=y<=mx?f[y][0]:f[n/y][1];
46             vis[now^z]=i;
47             if((i/y-i/(y+1))&1)now^=z;
48             //如果在范围里有偶数个z,那算下一个的范围的时候z就被自己消掉了所以不用算。
49         }
50         for(int j=1;;j++){//大家喜闻乐见的mex时间
51             if(vis[j]!=i){
52                 if(i<=mx)f[i][0]=j;else f[n/i][1]=j;
53                 break;
54             }
55         }
56     }
57     for(int i=1;i<=k;i++){
58         scanf("%d",&w);int x,ans=0;
59         for(int i=1;i<=w;i++){
60             scanf("%d",&x);
61             x=n/x;
62             ans^=x<=mx?f[x][0]:f[n/x][1];//喜闻乐见的异或时间
63         }
64         if(ans)printf("Yes\n");//喜闻乐见的判定时间
65         else printf("No\n");
66     }
67     return 0;
68 }
View Code

 

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

原文:https://www.cnblogs.com/137shoebills/p/8335034.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!