【bzoj4589】Hard Nim FWT+快速幂
题目大意:给你$n$个不大于$m$的质数,求有多少种方案,使得这$n$个数的异或和为$0$。其中,$n≤10^9,m≤10^5$。
考虑正常地dp,我们用$f[i][j]$表示前$i$个数的异或和为$j$的方案数。
我们构造一个数组$g$,若i为不大于$m$的质数,则$g[i]=1$,否则为$0$。
那么显然,$f[i][j]=\sum f[i-1][k]\times g[j \oplus k]$。 其中$j \oplus k$表示$j$和$k$的按位异或。
然后我们不难发现,$f[i]为f[i-1]$与$g$的异或卷积。
则$f[n]$为$g$的$n$次异或卷积,答案显然为$f[n][0]$。
我们用$FWT$将$g$变成点值表达式,然后做快速幂,最后再插值回来,就得到答案了。
时间复杂度为$O(m\ log\ m+m\ log\ n)$。
#include<bits/stdc++.h>
#define M 131072
#define L long long
#define MOD 1000000007
using namespace std;
int b[M]={},pri[M]={},use=;
void init(){
for(int i=;i<M;i++){
if(!b[i]) pri[++use]=i;
for(int j=;j<=use&&i*pri[j]<M;j++){
b[i*pri[j]]=;
if(i%pri[j]==) break;
}
}
}
L pow_mod(L x,int k){
L ans=;
while(k){
if(k&) ans=ans*x%MOD;
x=x*x%MOD; k>>=;
}
return ans;
}
void FWT(L a[],int n,int on){
for(int i=;i<n;i<<=)
for(int j=;j<n;j++)
if(i&j){
L w=a[i^j];
a[i^j]=(w+a[j])%MOD;
a[j]=(w-a[j]+MOD)%MOD;
}
if(on==-){
L inv=pow_mod(n,MOD-);
for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
}
}
L g[M]={},ans[M]={};
int main(){
init();
int t,n;
while(cin>>t>>n){
int len=; while(len<=n) len<<=;
for(int i=;i<=n;i++) if(b[i]==) g[i]=;
FWT(g,len,); memcpy(ans,g,M<<); t--;
while(t){
if(t&) for(int i=;i<len;i++) ans[i]=ans[i]*g[i]%MOD;
t>>=; for(int i=;i<len;i++) g[i]=g[i]*g[i]%MOD;
}
FWT(ans,len,-);
printf("%lld\n",ans[]);
memset(g,,len<<); memset(ans,,len<<);
}
}
【bzoj4589】Hard Nim FWT+快速幂的更多相关文章
- BZOJ4589: Hard Nim(FWT 快速幂)
题意 题目链接 Sol 神仙题Orzzzz 题目可以转化为从\(\leqslant M\)的质数中选出\(N\)个\(xor\)和为\(0\)的方案数 这样就好做多了 设\(f(x) = [x \te ...
- BZOJ4589 Hard Nim FWT 快速幂 博弈
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4589.html 题目传送门 - BZOJ4589 题意 有 $n$ 堆石子,每一堆石子的取值为 $2$ ...
- [bzoj4589]Hard Nim(FWT快速沃尔什变化+快速幂)
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=4589 题意 求选恰好n个数,满足每个数都是不大于m的质数,且它们的异或和为0的方案数. 解法 ...
- 【51Nod1773】A国的贸易 FWT+快速幂
题目描述 给出一个长度为 $2^n$ 的序列,编号从0开始.每次操作后,如果 $i$ 与 $j$ 的二进制表示只差一位则第 $i$ 个数会加上操作前的第 $j$ 个数.求 $t$ 次操作后序列中的每个 ...
- BZOJ4589 Hard Nim(快速沃尔什变换FWT)
这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...
- bzoj 4589: Hard Nim【线性筛+FWT+快速幂】
T了两次之后我突然意识到转成fwt形式之后,直接快速幂每次乘一下最后再逆回来即可,并不需要没此次都正反转化一次-- 就是根据nim的性质,先手必输是所有堆个数异或和为0,也就变成了一个裸的板子 #in ...
- bzoj4589: Hard Nim fwt
题意:求n个m以内的素数亦或起来为0的方案数 题解:fwt板子题,先预处理素数,把m以内素数加一遍(下标),然后fwt之后快速幂即可,在ifwt之后a[0]就是答案了 /*************** ...
- BZOJ4589 Hard Nim(快速沃尔什变换模板)
终于抽出时间来学了学,比FFT不知道好写到哪里去. #include <cstdio> typedef long long ll; ,p=1e9+; int k,m,n,a[N],pi[N ...
- BZOJ 4589 Hard Nim(FWT+博弈论+快速幂)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4589 [题目大意] 有n堆石子,每堆都是m以内的质数,请问后手必胜的局面有几种 [题解 ...
随机推荐
- 【JDBC】jdbc原理总结
1 什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库 ...
- Devexpress VCL Build v2013 vol 14.1.5 发布
What's New in 14.1.5 (VCL Product Line) New Major Features in 14.1 What's New in VCL Products 14.1 ...
- 2018.10.23 vijo1243生产产品(单调队列优化dp)
传送门 这道单调队列真的有点难写啊. 方程感觉挺简单的. f[i][j]f[i][j]f[i][j]表示在第iii个车间结束前jjj次步骤的最小代价. 然后用单调队列毒瘤优化一下就行了. 代码: #i ...
- 2018.09.27 bzoj2118: 墨墨的等式(最短路+背包)
传送门 好题啊. 首先找到最小的一个非零系数记做a1a_1a1,然后如果WWW modmodmod a1=W′a_1=W'a1=W′ modmodmod a1a_1a1,且WWW是方程的一个可行 ...
- 2018.09.27 bzoj4300: 绝世好题(二进制dp)
传送门 简单dp. 根据题目的描述. 如果数列bn{b_n}bn合法. 那么有:bi−1b_{i-1}bi−1&bi!=0b_i!=0bi!=0,因此我们用f[i]f[i]f[i]表示数 ...
- 2018.09.11 poj1845Sumdiv(质因数分解+二分求数列和)
传送门 显然需要先求出ab" role="presentation" style="position: relative;">abab的所有质因 ...
- Can not issue data manipulation statements with executeQuery().
这个错误提示是说无法发行sql语句到指定的位置 就是如图的两端代码的问题,excuteQuery是查询语句,而我要调用的是更新的语句,所以这样数据库很为难到底要干嘛,我实际的操作是要更新数据,所以把 ...
- HDU 1756 Cupid's Arrow (几何问题,判定点在多边形内部)
题意:中文的么,自己看喽. 析:很容易明白是判定点是不是在多边形内部,一般是向量来判定,我一开始用点在向量的右侧,因为是顺时针给的,只要点全在外侧或边上, 就可以,暴力一下就ok.由于这个是浮点数,一 ...
- 第一部分 Mysql的基础
一.登录: mysql -h localhost -u root -p #其中,-h表示后面跟着的是服务器主机地址,-u后面跟着的是用户名,-p表示密码# 本地测试: 账号: 二.也可以省略写成: m ...
- button 左边图片右边文字样式
状态值 : 正常 状态值 : 选中 #pragma mark - buttonPress- (void)buttonPress:(UIButton * )sender { if ( ...