【2018北京集训6】Lcm DFT&FWT
首先我们来看下此题的模数232792561。
232792561=lcm(1,2,3.......20)+1。这个性质将在求值时用到。
我们将n分解质因数,令$m$为$n$的素因子个数,设n=$\Pi_{j=0}^{m-1} p_j^{b_j}$ ,其中$p_j$是素数且$p_0$至$p_{m-1}$从小到大排列。考虑到$n≤10^{18}$,则$m≤15$。
我们用 $f[i][j]$ 表示当前$n$的因数$x$所表示的状态为$i$,且模$k$为$j$时的方案数。
下面讲下如何用一个已知的因数$x$求出$i$。
设$x=\Pi_{j=0}^{m-1} p_j^{d_j}$ ,则$i=\sum _{j=0}^{m-1} 2^{j} \times [d_j==b_j]$ 。(此处举个例子,令$n=12$,则当$x=6$时,$i=2$,当$x=12$时,$i=3$,如果还是不清楚的话可以去看我的代码)
据此定义,则答案显然为$f[2^{m}-1][0]$。
初始化:对于$\forall n \% x==0$ 有 $f[i][x \% k]=1$
下面考虑如何转移。
显然,朴素的转移方法是会超时的(说白了就是只有10分),那么考虑如何加速转移。
首先,我们现在$f[i][0...2^{m}-1][]$中完成同层的转移(详情见代码)
假设我们去取出数量相同的$c$和b,使得$\Pi f[b_l][c_i]$ 可以对$f[2^m-1][0]$产生贡献。
考虑可对$f[2^m-1][0]$产生贡献的条件,显然有三:
$b_1 \ or\ b_2 \ or \ .....b_p=2^m-1 $
$b_1 \ne b_2 \ne ..... \ne b_p$
$c_1\ +\ c_2\ +\ .....\ c_p\ \equiv 0 (mod \ k)$
对于这两条限制,直接对每一行(既$f[i]$)先做一次DFT以满足性质3,然后对每一列(即$f[][j]$)做一次FWT以满足性质1和性质2(没错通过这种嵌套即可同时满足两个性质),然后将最后一列做一次IDFT,即可求出$f[2^m-1][0]$
此题看题5分钟,懵逼4小时,写题1小时.....
#include<bits/stdc++.h>
#define M 20000000
#define MOD 232792561
#define L long long
using namespace std;
L pow_mod(L x,int k){
L ans=;
while(k){
if(k&) ans=ans*x%MOD;
x=x*x%MOD; k>>=;
}
return ans;
}
L f[<<][]={};
L n,m,nn,e[]={},d[]={},p[]={},a[M]={}; int k; void DFT(L a[],L w[],int n,int on){
L b[]; memset(b,,sizeof(b));
for(int i=;i<n;i++)
for(int j=;j<n;j++)
b[i]=(b[i]+a[j]*w[i*j])%MOD;
memcpy(a,b,);
if(on==-){
L inv=pow_mod(n,MOD-);
for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
}
} void fenjie(L n){//分解质因数
for(int i=;i<=;i++)
if(n%i==){
m++; p[m]=i; e[m]=;
while(n%i==) n/=i,d[m]++,e[m]*=i;
}
}
void coushu(int x,L ji){//凑出所有约数
if(x>m) {a[++nn]=ji; return;}
coushu(x+,ji);
for(int i=;i<=d[x];i++){
ji*=p[x];
coushu(x+,ji);
}
} void add(int x,int nk){
L b[];
memcpy(b,f[x],);
for(int i=;i<k;i++)
f[x][i]=(f[x][i]+b[(i-nk+k)%k])%MOD;
f[x][nk]=(f[x][nk]+)%MOD;
}
L w1[]={},w2[]={};
void sub(){
memset(e,,sizeof(e)); memset(d,,sizeof(d));
memset(p,,sizeof(p)); memset(a,,sizeof(a));
memset(f,,sizeof(f)); m=nn=;
cin>>n>>k;
L w=pow_mod(,(MOD-)/k); w1[]=w2[]=;
for(int i=;i<;i++){
w1[i]=w1[i-]*w%MOD;
w2[i]=pow_mod(w1[i],MOD-);
}
m=; fenjie(n);
coushu(,);
for(int i=;i<=nn;i++){
int id=;
for(int j=;j<=m;j++)
if(a[i]%e[j]==) id=id|(<<(j-));
add(id,a[i]%k);
}
int mm=<<m;
for(int i=;i<mm;i++) DFT(f[i],w1,k,);
for(int i=;i<mm;i++)
for(int j=;j<k;j++) f[i][j]++; for(int i=;i<mm;i<<=)
for(int j=;j<mm;j++)
if(i&j){
for(int l=;l<k;l++)
f[j][l]=f[j][l]*f[i^j][l]%MOD;
}
for(int i=;i<mm;i<<=)
for(int j=;j<mm;j++)
if(i&j){
for(int l=;l<k;l++)
f[j][l]=(f[j][l]-f[i^j][l]+MOD)%MOD;
}
DFT(f[mm-],w2,k,-);
printf("%lld\n",f[mm-][]);
} int main(){
int cas; scanf("%d",&cas);
while(cas--) sub();
}
【2018北京集训6】Lcm DFT&FWT的更多相关文章
- 【2018北京集训(六)】Lcm
Portal --> 出错啦qwq(好吧其实是没有) Description 给定两个正整数\(n,k\),选择一些互不相同的正整数,满足这些数的最小公倍数恰好为\(n\),并且这些数的和为\( ...
- 【2018北京集训十二】 coin 矩阵快速幂
矩阵快速幂原来还可以这么用?? 你们城里人还真会玩. 我们令$f[i][j][k]$表示总的钱数为i,当前使用的最大面值硬币的面值为$v_j$,最小为$v_k$的方案数量. 不难发现$f[i][j][ ...
- 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)
牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...
- 【北京集训D2T3】tvt
[北京集训D2T3]tvt \(n,q \le 1e9\) 题目分析: 首先需要对两条路径求交,对给出的四个点的6个lca进行分类讨论.易于发现路径的交就是这六个lca里面最深的两个所形成的链. 然后 ...
- (2016北京集训十)【xsy1528】azelso - 概率期望dp
北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...
- 【2017 北京集训 String 改编版】子串
题意 你有一个字符串,你需要支持两种操作: 1:在字符串的末尾插入一个字符 \(c\) 2:询问当前字符串的 \([l,r]\) 子串中的不同子串个数 为了加大难度,操作会被加密(强制在线). \(n ...
- 【XSY2753】Lcm 分治 FWT FFT 容斥
题目描述 给你\(n,k\),要你选一些互不相同的正整数,满足这些数的\(lcm\)为\(n\),且这些数的和为\(k\)的倍数. 求选择的方案数.对\(232792561\)取模. \(n\leq ...
- [2016北京集训试题15]项链-[FFT]
Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...
- 【集训Day4 动态规划】【2018寒假集训 Day4 更新】蛙人
蛙人 (ple) 蛙人使用特殊设备潜水.设备中有一个气瓶,分两格:一格装氧气,另一格装氮气.留在水中有时间的限制,在深水中需要大量的氧气与氮气.为完成任务,蛙人必须安排好气瓶.每个气瓶可以用它的重量和 ...
随机推荐
- 661. Image Smoother
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 2018.07.10NOIP模拟 Knapsack(单调队列优化dp)
Knapsack 题目背景 SOURCE:NOIP2016-RZZ-4 T2 题目描述 有 n 个物品,第 i 个物品的重量为 ai . 设 f(i,j,k,l,m) 为满足以下约束的物品集合数量: ...
- 数塔问题-hdu-2084(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084 思路:要求从顶到底的最大值,可以反过来考虑,从底部向上. 只有下面一行的最大值确定,这一行的最大 ...
- java程序设计基本概念 jvm
JVM (1)对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中.对于equals相等的字符串 ...
- 20155211 2016-2017-2 《Java程序设计》第七周学习总结
20155211 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 第十二章 Lambda Lambda表达式中this的参考对象以及toString()的接受 ...
- webuploader传递参数
实际开发过程中,比如我有个工单提交系统,提交工单的时候用webuploader上传图片,如果工单的ID是自增长类型的,那么我在上传图片的时候肯定需要关联上工单的id,这时候就需要通过webupload ...
- excel如何设置自增序列
见图1 见图2 4,如果内容对您有所帮助,请打赏---1毛就足够感动我,诚信交友~
- 快速排序—三路快排 vs 双基准
快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...
- java web eclipse中项目的加载过程
java web eclipse中项目的加载过程: Tomcat默认从WEB-INF/目录下加载资源,Eclipse在发布程序的时候,并没有把User Libraries的相关资源拷贝到WEB-INF ...
- Java泛型与Restlet客户端
写一个与restlet服务器通信的客户端类,用于测试通信是否成功,并且进行交互.为了方便其他人使用,于是,写一个通用的方法封装起来,可是中途却放生了一些问题. 按照正常写法,顺序走下来是这样的: pu ...