【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以内的质数,请问后手必胜的局面有几种 [题解 ...
随机推荐
- 2018.07.20 bzoj3211: 花神游历各国(线段树)
传送门 维护区间开方,区间求和.这个是线段树常规操作. 显然一个数被开方若干次之后要么是1,要么是0,所以用线段树维护区间最大和区间和,如果区间最大不超过1就剪枝剪掉,不然就继续递归直到叶节点时停下进 ...
- springcloud-eureka简单实现
请参考 spring+cloud为服务实战 第三章 一.创建Eureka服务 1.使用Idea创建一个项目 结构如下: 2.pom.xml配置: <?xml version="1.0& ...
- T4系列文章之2:T4工具简介、调试以及T4运行原理(转)
出处:http://www.cnblogs.com/damonlan/archive/2012/01/12/2320429.html 一.前言 经过第一篇,我想大家现在对T4有了基本的印象,应该对T4 ...
- git分支删除
1.列出本地分支: git branch 2.删除本地分支: git branch -D BranchName 其中-D也可以是--delete,如: git branch --delete Bran ...
- Hdu1401 Solitaire 2017-01-18 17:21 33人阅读 评论(0) 收藏
Solitaire Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Sub ...
- android周期性任务
一般任务调度机制的实现方式主要有: Thread sleep.Timer.ScheduledExecutor.Handler和其他第三方开源库.android的AlarmManager 1. Time ...
- n&&m and n||m 的区别
今天写一道题老是WA最后才发现问题出在了这个地方, 题目说的是当输入的n和m 都为0的时候,结束输入. 于是乎,条件我就写成了while(n&&m),其实这句话的意思是:只有m和n都不 ...
- 为spring代理类设置属性值
现在有一个bean包含了私有属性,如下: @Component public class Bean { String name; public String getName() { return na ...
- R12_专题知识总结提炼-AP模块
应付模块业务操作流程 供应商管理 供应商概述 在您使用 Oracle Purchasing 之前,需要定义供应商.供应商site,以及供应商联系人, 供应商主数据(SUPPLIER MASTER D ...
- 安卓读写INI文件
安卓读写INI文件 uses System.IoUtils procedure TForm1.Button1Click(Sender: TObject);var IniFile:TIniFile; C ...