原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4589.html

题目传送门 - BZOJ4589

题意

  有 $n$ 堆石子,每一堆石子的取值为 $2$ ~ $m$ 之间的素数。

  问在所有不同的取值中,先手必败的方案总数。

  答案对 $10^9+7$ 取模。

  $n\leq 10^9,m\leq 50000$

题解

  第一次写 FWT

  感觉 FWT 比 FFT 简单多了。

  下面进入正题。

  首先,我们再回顾一下 Nim游戏 中先手必败的情况:所有数的异或和为 $0$ 。具体证明自行百度,这里不加赘述。

  我们构造一个多项式 $A$ ,如果 $i$ 为素数,那么 $A(i)=1$ ,否则 $A(i)=0$ 。

  定义卷积如下形式:

$$C(k)=\sum_{i\ XOR\ j=k} A(i)B(j)$$

  于是我们看到,如果 $n=2$ ,那么答案为 $A^2(0)$ 。

  类似地,原题答案为 $A^n(0)$ 。

  注意一下上面的那个卷积式可以用 FWT 来做。

  我们先 FWT 一下,类似于多项式点值相乘,异或卷积的“点值”也可以自己相乘,于是每一个值都直接取其 $n$ 次方,然后再 IFWT 一下就可以得到目标多项式了。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1<<16,mod=1e9+7,inv2=(mod+1)/2;
int Pow(int x,int y){
if (!y)
return 1;
int xx=Pow(x,y/2);
xx=1LL*xx*xx%mod;
if (y&1)
xx=1LL*xx*x%mod;
return xx;
}
bool check(int x){
for (int i=2;i*i<=x;i++)
if (x%i==0)
return 0;
return x>1;
}
int n,m,k,A[N];
void FWT(int a[],int n,int flag){
for (int d=1;d<n;d<<=1)
for (int i=0;i<n;i+=(d<<1))
for (int j=0;j<d;j++){
int x=a[i+j],y=a[i+j+d];
a[i+j]=(x+y)%mod;
a[i+j+d]=(x-y+mod)%mod;
if (flag<0){
a[i+j]=1LL*a[i+j]*inv2%mod;
a[i+j+d]=1LL*a[i+j+d]*inv2%mod;
}
}
}
int main(){
while (~scanf("%d%d",&k,&m)){
for (n=1;n<=m;n<<=1);
for (int i=0;i<n;i++)
A[i]=(check(i)&&i<=m)?1:0;
FWT(A,n,1);
for (int i=0;i<n;i++)
A[i]=Pow(A[i],k);
FWT(A,n,-1);
printf("%d\n",A[0]);
}
return 0;
}

  

BZOJ4589 Hard Nim FWT 快速幂 博弈的更多相关文章

  1. BZOJ4589: Hard Nim(FWT 快速幂)

    题意 题目链接 Sol 神仙题Orzzzz 题目可以转化为从\(\leqslant M\)的质数中选出\(N\)个\(xor\)和为\(0\)的方案数 这样就好做多了 设\(f(x) = [x \te ...

  2. 【bzoj4589】Hard Nim FWT+快速幂

    题目大意:给你$n$个不大于$m$的质数,求有多少种方案,使得这$n$个数的异或和为$0$.其中,$n≤10^9,m≤10^5$. 考虑正常地dp,我们用$f[i][j]$表示前$i$个数的异或和为$ ...

  3. [bzoj4589]Hard Nim(FWT快速沃尔什变化+快速幂)

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=4589 题意 求选恰好n个数,满足每个数都是不大于m的质数,且它们的异或和为0的方案数. 解法 ...

  4. 【51Nod1773】A国的贸易 FWT+快速幂

    题目描述 给出一个长度为 $2^n$ 的序列,编号从0开始.每次操作后,如果 $i$ 与 $j$ 的二进制表示只差一位则第 $i$ 个数会加上操作前的第 $j$ 个数.求 $t$ 次操作后序列中的每个 ...

  5. BZOJ4589 Hard Nim(快速沃尔什变换FWT)

    这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...

  6. bzoj 4589: Hard Nim【线性筛+FWT+快速幂】

    T了两次之后我突然意识到转成fwt形式之后,直接快速幂每次乘一下最后再逆回来即可,并不需要没此次都正反转化一次-- 就是根据nim的性质,先手必输是所有堆个数异或和为0,也就变成了一个裸的板子 #in ...

  7. bzoj4589: Hard Nim fwt

    题意:求n个m以内的素数亦或起来为0的方案数 题解:fwt板子题,先预处理素数,把m以内素数加一遍(下标),然后fwt之后快速幂即可,在ifwt之后a[0]就是答案了 /*************** ...

  8. BZOJ4589 Hard Nim(快速沃尔什变换模板)

    终于抽出时间来学了学,比FFT不知道好写到哪里去. #include <cstdio> typedef long long ll; ,p=1e9+; int k,m,n,a[N],pi[N ...

  9. BZOJ4589 Hard Nim(博弈+FWT)

    即使n个数的异或为0.如果只有两堆,将质数筛出来设为1,做一个异或卷积即可.显然这个东西满足结合律,多堆时直接快速幂.可以在点值表示下进行. #include<iostream> #inc ...

随机推荐

  1. boost.Asio lib

    Documentation for Boost.Asio http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio.html https://w ...

  2. WINDOWS资源编译器出错信息

    ACCELERATORS语句的type域应包含ASCⅡ值或VIRTKEY值.        BEGIN expected in table        BEGIN关键字应紧跟在ACCELERATOR ...

  3. js浏览器判断函数

    function userBrowser(){ var browserName=navigator.userAgent.toLowerCase(); if(/msie/i.test(browserNa ...

  4. awk简单用法-(1)

    一.awk基本操作 awk指定多个分割符,分隔符中有:和空格,还有:和空格的组合,这个时候需要指定多个分隔符 -F'[ :]+',[ :]表示分隔符为:和空格,一个或者多个+号表示空格和:的组合也为一 ...

  5. Ftp上传的方法

    using System;using System.Collections.Generic;using System.IO;using System.Net;using System.Text; na ...

  6. Confluence 6 通过 SSL 或 HTTPS 运行 - 重定向所有的 URLS 到 HTTPS 的安全考虑

    尽管现在 HTTPS 现在已经激活并且可用了.老的 HTTP URLs (http://localhost:8090)还是可以访问的.现在你需要重定向所有 URLs 到他们的 HTTPS 链接中.你可 ...

  7. usrp-B210

    sudo add-apt-repository ppa:ettusresearch/uhd sudo apt-get update sudo apt-get install libuhd-dev li ...

  8. CSS3媒体查询的部分重要属性

    width:视口宽度 height:视口高度 device-width:渲染表面的宽度,就是设备屏幕的宽度 device-height:渲染表面的高度,就是设备屏幕的高度 orientation:检查 ...

  9. MySQL基于ROW格式的数据恢复

    大家都知道MySQL Binlog 有三种格式,分别是Statement.Row.Mixd.Statement记录了用户执行的原始SQL,而Row则是记录了行的修改情况,在MySQL 5.6以上的版本 ...

  10. centos--git搭建之Gogs安装

    1.下载git yum intall -y git 2. 创建git用户(必须新创建git用户, 用root用户会导致无法下载) #创建git用户 sudo adduser git #给git用户设置 ...