BZOJ4589:Hard Nim——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4589
Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下:1. Claris和NanoApe两个人轮流拿石子,Claris先拿。2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负。Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种。由于答案可能很大,你只需要给出答案对10^9+7取模的值。
天哪这个tinymce可以用latex我才知道……以及我还是想不到dp啊。
用到一个结论:后手获胜条件是每堆石子异或和为0。
设$f[i][j]$为前$i$堆异或和为$j$的方案数,$g[i]$表示$i$是否为质数。
于是$f[i][j]=\sum_{k=0}^mf[i-1][j\oplus k]g[k]$
然后变成卷积就是$f[i][j]=\sum_{a\oplus b=j}f[i-1][a]g[b]$
同样还是把$f[i-1][a]$递归展开发现是卷积套卷积……n次,于是FWT快速幂就好了。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+;
const int p=1e9+;
const int inv=;
inline int add(int x,int y){
x+=y;if(x>=p)x-=p;return x;
}
inline int sub(int x,int y){
x-=y;if(x<)x+=p;return x;
}
void FWT(int a[],int n,int on){
for(int i=;i<n;i<<=){
for(int j=;j<n;j+=(i<<)){
for(int k=;k<i;k++){
int u=a[j+k],t=a[j+k+i];
a[j+k]=add(u,t);
a[j+k+i]=sub(u,t);
if(on==-){
a[j+k]=(ll)a[j+k]*inv%p;
a[j+k+i]=(ll)a[j+k+i]*inv%p;
}
}
}
}
}
int qpow(int k,int n){
int res=;
while(n){
if(n&)res=(ll)res*k%p;
k=(ll)k*k%p;n>>=;
}
return res;
}
int pri[N],g[N],a[N],b[N],tot;
void Euler(int n){
g[]=g[]=;
for(int i=;i<=n;i++){
if(!g[i])pri[++tot]=i;
for(int j=;j<=tot;j++){
if(i*pri[j]>n)break;
g[i*pri[j]]=;
if(i%pri[j]==)break;
}
}
for(int i=;i<=n;i++)g[i]^=;
}
int n,m;
int main(){
Euler(5e4);
while(scanf("%d%d",&n,&m)!=EOF){
int len=;
while(len<=m)len<<=;
memset(a,,sizeof(a));
memset(b,,sizeof(b));
a[]=;
for(int i=;i<=m;i++)b[i]=g[i];
FWT(a,len,);FWT(b,len,);
for(int i=;i<len;i++)a[i]=(ll)a[i]*qpow(b[i],n)%p;
FWT(a,len,-);
printf("%d\n",a[]);
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ4589:Hard Nim——题解的更多相关文章
- BZOJ4589 Hard Nim FWT 快速幂 博弈
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4589.html 题目传送门 - BZOJ4589 题意 有 $n$ 堆石子,每一堆石子的取值为 $2$ ...
- BZOJ4589 Hard Nim 【FWT】
题目链接 BZOJ4589 题解 FWT 模板题 #include<algorithm> #include<iostream> #include<cstdlib> ...
- BZOJ4589 Hard Nim(博弈+FWT)
即使n个数的异或为0.如果只有两堆,将质数筛出来设为1,做一个异或卷积即可.显然这个东西满足结合律,多堆时直接快速幂.可以在点值表示下进行. #include<iostream> #inc ...
- BZOJ4589 Hard Nim(快速沃尔什变换FWT)
这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...
- bzoj4589: Hard Nim fwt
题意:求n个m以内的素数亦或起来为0的方案数 题解:fwt板子题,先预处理素数,把m以内素数加一遍(下标),然后fwt之后快速幂即可,在ifwt之后a[0]就是答案了 /*************** ...
- [BZOJ4589]Hard Nim
description BZOJ 题意:\(n\)堆式子,每堆石子数量为\(\le m\)的质数,对于每一个局面玩\(Nim\)游戏,求后手必胜的方案数. data range \[n\le 10^9 ...
- Forethought Future Cup - Final Round (Onsite Finalists Only) C. Thanos Nim 题解(博弈+思维)
题目链接 题目大意 给你n堆石子(n为偶数),两个人玩游戏,每次选取n/2堆不为0的石子,然后从这n/2堆石子中丢掉一些石子(每一堆丢弃的石子数量可以不一样,但不能为0),若这次操作中没有n/2堆不为 ...
- BZOJ4589 Hard Nim(快速沃尔什变换模板)
终于抽出时间来学了学,比FFT不知道好写到哪里去. #include <cstdio> typedef long long ll; ,p=1e9+; int k,m,n,a[N],pi[N ...
- bzoj千题计划308:bzoj4589: Hard Nim(倍增FWT+生成函数)
https://www.lydsy.com/JudgeOnline/problem.php?id=4589 n*m*m 做法 dp[i][j] 前i堆石子,异或和为j的方案数 第一重循环可以矩阵快速幂 ...
随机推荐
- 一个只有十行的精简MVVM框架(上篇)
本文来自网易云社区. 前言 MVVM模式相信做前端的人都不陌生,去网上搜MVVM,会出现一大堆关于MVVM模式的博文,但是这些博文大多都只是用图片和文字来进行抽象的概念讲解,对于刚接触MVVM模式的新 ...
- 使数据可供ArcGIS Server访问
内容来自ESRI官方文档(点击访问),简单总结如下: 1 ArcGIS Server用于发布服务的数据必须存储在服务器可以访问的位置: 2 这样的位置有三种类型: 本地路径:将数据本地存储在每台 Ar ...
- android学习五 Intent
1.Intent是组件间调用的桥梁. 2.Android系统定义了很多Intent http://developer.android.com/guide/components/intents-c ...
- 【白书训练指南】(UVa10755)Garbage Heap
先po代码,之后把我那几个不太明了的知识点讲讲,巩固以下.三维的扫描线算法想要掌握还真是有一定的难度的. 代码 #include <iostream> #include <cstri ...
- 通过 Python_Faker 生成测试数据
通过 Python_Faker 生成测试数据 一.介绍 在软件需求.开发.测试过程中,有时候需要使用一些测试数据,针对这种情况,我们一般要么使用已有的系统数据,你不可能通过手工来生成(最傻的方法)可能 ...
- Java注解的基本原理
注解的本质就是一个继承了Annotation接口的接口,一个注解准确意义上来说,只不过是一种特殊注释而已,如果没有解析他的代码,他可能连注释都不如. 解析一个类或者方法的注解往往有两种形式,一种是编译 ...
- 幸运的袋子(深度优先遍历(Depth First Search,DFS))
题目描述 一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的).如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积. 例如:如果袋子里面的球的号码是{1, 1, 2 ...
- CTC (Connectionist Temporal Classification) 算法原理
(原创文章,转载请注明出处哦~) 简单介绍CTC算法 CTC是序列标注问题中的一种损失函数. 传统序列标注算法需要每一时刻输入与输出符号完全对齐.而CTC扩展了标签集合,添加空元素. 在使用扩展标签集 ...
- Paper Reading - CNN+CNN: Convolutional Decoders for Image Captioning
Link of the Paper: https://arxiv.org/abs/1805.09019 Innovations: The authors propose a CNN + CNN fra ...
- Spring Boot - Filter实现简单的Http Basic认证
Copy自http://blog.csdn.net/sun_t89/article/details/51916834 @SpringBootApplicationpublic class Spring ...