Description

  

  给你\(n,k\),要你选一些互不相同的正整数,满足这些数的lcm为\(n\),且这些数的和为\(k\)的倍数。

  

  求选择的方案数。对\(232792561\)取模。

  

  \(n\le10^{18},k\le20,n的全部质因子都\le100\)

   

  

  

Solution

  

  \(n\le10^{18}\)时其质因数个数最多只有15个。记\(n\)的质因子个数为\(m\)。

  

​  设\(g_{i,j}\)表示有多少个\(n\)的因数\(d\),满足\(d\)中\(i\)状态的质因子的指数与\(n\)相同,且\(d\%k=j\)。

  

  再设\(f_{i,j}\),表示从\(g_{i}\)所涉及的数组成的数集\(A_i\)中有多少个子集,使得子集中的数之和模\(k\)为\(j\)。

  

  这点可以用生成函数解决:

\[G_i(x)=\prod_{a\in A_i}(1+x^a)
\]

  则\(f_{i,j}=G_i(x)[j]\)。

  

​  考虑许多个\(f_{i,j}\)怎样组合才对答案有贡献。当下列条件同时满足时:

  

  (1)\(i_1|i_2|...|i_s=2^m-1\)

  

​  (2)\(i_1\neq i_2\neq...\neq i_s\)

  

​  (3)\(j_1+j_2+...+j_s\equiv0\pmod k\)

  

  则会对\(Ans\)有\(\prod f_{i,j}\)的贡献。

  

  其实我们要求一个数组\(h_{i,j}\)表示任选所有数字,使得\(i\)状态表示的每个质因子\(p\),至少存在一个数满足其\(p\)的指数与\(n\)中相同,且所有数加起来模\(k\)等于\(j\)的方案数。显然答案是\(h_{2^m-1,0}\)。

  

  对每一行\(f_i\)单独做一次DFT,此时得到每行\(f_i\)的点值表达。我们要做的,是选择那些编号或起来恰好等于\(2^m-1\)的行,将它们的点值表达对位相乘,累加到一个新数组\(tmp\),这相当于枚举哪些行参与贡献、枚举这些行的哪一个\(f_{i,j}\)参与贡献。对此\(tmp\)做逆DFT,就可以得到\(h_{i}\)了!

  

  所以这部分如何操作?我们发现每一列的操作模式是相同的且互不影响。那么现在我们只看第一列即\(f_{i,0}\),将这一列数拉出来方便看,设为\(a_i\),其中\(a_i=DFT(f_i)[0]\)。

  

​  另起一个命名空间:\(f_i\)表示从\(a\)中选择若干个数使得编号或起来等于\(i\)时所有选择数的乘积,的所有情况之和。

  

  构造莫比乌斯变换\(F_S=\sum_{T\in S}{f_T}=\prod_{i\in S}(1+a_i)\)。最后一个式子只要将括号展开,会得到许多乘积之和,每一个乘积都属于某一个\(f\),因此是成立的。

  

  根据莫比乌斯反演,有\(f_S=\sum_{T\in S}(-1)^{|S|-|T|}F_T\),因此若我们知道\(F\),就可以暴力地求\(f_{2^m-1}\)。那么\(f_{2^m-1}\)其实就是\(tmp\)的第0项,因为它是一种或的组合形式,满足粗体字,解决了一列的操作,那么其他列同理。

  

​  \(F\)怎么求呢?这里要用到快速莫比乌斯变换FMT,即求解\(F_S=\prod_{T\in S}g(T)\),其中\(g\)是一个已知函数。

  

​  初始时\(F_S=g(S)\)。考虑补全\(F_S\)的内容,即考虑自己\(F_i\)如何去补全别人的\(F_j\)。有一种方式可以无重复地做到这点。\(F_i\)能更新\(F_j\)当且仅当\(j\)是由\(i\)的某一位0改成1得到。从低到高枚举改第\(x\)位,之后从小到大循环\(i\),如果\(i\)的第\(x\)位是0,那么更新\(F_{i+2^x}+=F_i\)。为什么要这样做?因为这样每个\(F_i\)所包含的元素都会只统计一次。假设\(F_i\)中\(g(j)\)被统计了多次,那就说明\(g(j)\)贡献去\(F_i\)的路径出现分叉和合并,即有人先改了高位、有人又先改了低位,两个过程又是同时进行的,这与我们算法设计的“逐位修改”有矛盾。因此可以这么做。

  

​  总时间复杂度\(\mathcal O(k^22^m+km2^m)\)。

  

​  交题不小心把yww的std交上去了,常数太优秀,我的代码覆盖不掉他。qwq

    

  

  

Code

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int PN=26,MOD=232792561,G=71;
ll n;
int m;
int d[PN],id[PN],idcnt,w[410][2];
int p[PN]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
int f[1<<15][20];
inline int bit(int i){return 1<<(i-1);}
int fmi(int x,int y,int mod=MOD){
int res=1;
for(;y;x=1LL*x*x%mod,y>>=1)
if(y&1) res=1LL*res*x%mod;
return res;
}
void init_rt(){
int rt=fmi(G,(MOD-1)/m);
w[0][0]=1;
for(int i=1;i<=400;i++) w[i][0]=1LL*w[i-1][0]*rt%MOD;
for(int i=0;i<=400;i++) w[i][1]=fmi(w[i][0],MOD-2);
}
void dft(int n,int *a,int t){
static int b[30];
for(int i=0;i<n;i++) b[i]=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
(b[i]+=1LL*a[j]*w[i*j][t]%MOD)%=MOD;
if(t){
int invn=fmi(n,MOD-2);
for(int i=0;i<n;i++) b[i]=1LL*b[i]*invn%MOD;
}
for(int i=0;i<n;i++) a[i]=b[i];
}
void depart(){
ll x=n;
for(int i=1;i<PN;i++){
d[i]=0;
while(x%p[i]==0) x/=p[i],d[i]++;
if(d[i]) id[i]=++idcnt;
}
}
void add(int x,int y){
static int t[30];
for(int i=0;i<m;i++) t[i]=f[x][i];
for(int i=0;i<m;i++)
(f[x][(i+y)%m]+=t[i])%=MOD;
}
void dfsdiv(int x,int state,int mulmodk){
if(x==PN){
add(state,mulmodk);
return;
}
for(int i=0;i<=d[x];i++){
if(i&&(i==d[x]))
dfsdiv(x+1,state|bit(id[x]),1LL*mulmodk*fmi(p[x],i,m)%m);
else
dfsdiv(x+1,state,1LL*mulmodk*fmi(p[x],i,m)%m);
}
}
void reset(){
memset(f,0,sizeof f);
}
void Main(){
scanf("%lld%d",&n,&m);
init_rt();
idcnt=0;
depart();
int all=1<<idcnt;
for(int i=0;i<all;i++){
f[i][0]=1;
for(int j=1;j<m;j++) f[i][j]=0;
}
dfsdiv(1,0,1);
for(int i=0;i<all;i++) dft(m,f[i],0);
for(int i=1;i<all;i<<=1)
for(int j=0;j<all;j++)
if(!(i&j))
for(int k=0;k<m;k++)
f[j+i][k]=1LL*f[j+i][k]*f[j][k]%MOD;
for(int i=0;i<all-1;i++){
int a=1;
for(int j=0;j<idcnt;j++)
if(!((i>>j)&1)) a=-a;
for(int j=0;j<m;j++)
(f[all-1][j]+=a*f[i][j])%=MOD;
}
dft(m,f[all-1],1);
int ans=f[all-1][0];
printf("%d\n",ans<0?ans+MOD:ans);
}
int main(){
int T;
scanf("%d",&T);
while(T--) Main();
return 0;
}

【XSY2753】LCM的更多相关文章

  1. 【XSY2753】Lcm 分治 FWT FFT 容斥

    题目描述 给你\(n,k\),要你选一些互不相同的正整数,满足这些数的\(lcm\)为\(n\),且这些数的和为\(k\)的倍数. 求选择的方案数.对\(232792561\)取模. \(n\leq ...

  2. 【倍增】LCM QUERY

    给一个序列,每次给一个长度l,问长度为l的区间中lcm最小的. 题解:因为ai<60,所以以某个点为左端点的区间的lcm只有最多60种的情况,而且相同的lcm区间的连续的. 所以就想到一个n*6 ...

  3. 【BZOJ】【2694】Lcm

    数论/莫比乌斯反演/线性筛 题解:http://www.cnblogs.com/zyfzyf/p/4218176.html JZPTAB的加强版?感觉线性筛好像还是不怎么会啊……sad 题目记下来,回 ...

  4. 【bzoj2694】Lcm 莫比乌斯反演+线性筛

    题目描述 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^m|\mu(gcd(i,j))|lcm(i,j)$,即$gcd(i,j)$不存在平方因子的$lcm(i,j)$之 ...

  5. 【CF1068B】LCM(数学)

    题意:给定b,求lcm(a,b)/a有几种不同的取值 b<=1e10 思路:只有a取b的因子时答案两两不同 #include<cstdio> #include<cstring& ...

  6. 【XSY2470】lcm 数学

    题目大意 \(t\)组询问, 每组询问给定\(n\),求\(\sum_{k=1}^n[n,k]\),其中\([a,b]\)表示\(a\)和\(b\)的最小公倍数 . \(t\leq 300000,n\ ...

  7. 【51NOD-0】1012 最小公倍数LCM

    [算法]欧几里德算法 #include<cstdio> int gcd(int a,int b) {?a:gcd(b,a%b);} int main() { int a,b; scanf( ...

  8. 【原创】开源Math.NET基础数学类库使用(09)相关数论函数使用

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  9. 【wikioi】1012 最大公约数和最小公倍数问题

    题目链接 算法:辗转相除(欧几里得) gcd(a, b)是a和b最小公倍数, lcm(a, b)是a和b的最大公倍数 gcd(a, b) == gcd(b, a%b) 时间复杂度: O(lgb) 具体 ...

随机推荐

  1. Unity中容易被忽略的小技巧

    今天在游戏蛮牛上看到慕容小匹夫的一篇文章,感觉对自己现在的水平很实用,就给转载了过来,以便日后好温习一下. 这里还是要支持原创作者,原文地址在这里 一.编辑器染色 一个常见的工作情景是我们在调整场景内 ...

  2. linux_connect_mysql

    原文来自 https://www.cnblogs.com/lywy510/p/3615710.html #include <stdio.h> #include <stdlib.h&g ...

  3. Hyperledger Fabric chaincode 开发(疑难解答)

    Q&A Q1: 使用fabric release 1.2 进行golang chaincode开发时报错: ..\..\hyperledger\fabric\vendor\github.com ...

  4. P4562 [JXOI2018]游戏

    题面 题目描述 她长大以后创业了,开了一个公司. 但是管理公司是一个很累人的活,员工们经常背着可怜偷懒,可怜需要时不时对办公室进行检查. 可怜公司有 \(n\) 个办公室,办公室编号是 \(l\) 到 ...

  5. Cocos2dx源码赏析(3)之事件分发

    Cocos2dx源码赏析(3)之事件分发 这篇,继续从源码的角度赏析下Cocos2dx引擎的另一模块事件分发处理机制.引擎的版本是3.14.同时,也是学习总结的过程,希望通过这种方式来加深对Cocos ...

  6. du命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/linuxnews/article/details/51207738 导读du命令是检查硬盘使用情况,统计文件或目录及子目录 ...

  7. django_models后台管理myarya

    arya重点代码 # urls.py from django.urls import path,re_path,include from arya.service import v1 urlpatte ...

  8. 王者荣耀交流协会final发布第五次scrum例会

    1.例会照片 成员高远博,冉华,王磊,王玉玲,任思佳,袁玥,王磊,王超. master:王磊 2.时间跨度 2017年12月5日 18:00 — 18:21,总计21分钟 3.地点 一食堂二楼沙发座椅 ...

  9. (第十周)评论Beta发布

    本人所在组:奋斗吧兄弟 按课上展示的顺序对每组进行点评: 1.  飞天小女警 项目:礼物挑选工具 相对于alpha发布时有了很大的进步.项目的界面很漂亮,这个项目的想法很新颖,我很喜欢.礼物的挑选给出 ...

  10. <!CDATA[]]用法详解

    所有 XML 文档中的文本均会被解析器解析. 只有 CDATA 区段(CDATA section)中的文本会被解析器忽略. PCDATA PCDATA 指的是被解析的字符数据(Parsed Chara ...