首先我们来看下此题的模数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小时.....

  1. #include<bits/stdc++.h>
  2. #define M 20000000
  3. #define MOD 232792561
  4. #define L long long
  5. using namespace std;
  6. L pow_mod(L x,int k){
  7. L ans=;
  8. while(k){
  9. if(k&) ans=ans*x%MOD;
  10. x=x*x%MOD; k>>=;
  11. }
  12. return ans;
  13. }
  14. L f[<<][]={};
  15. L n,m,nn,e[]={},d[]={},p[]={},a[M]={}; int k;
  16.  
  17. void DFT(L a[],L w[],int n,int on){
  18. L b[]; memset(b,,sizeof(b));
  19. for(int i=;i<n;i++)
  20. for(int j=;j<n;j++)
  21. b[i]=(b[i]+a[j]*w[i*j])%MOD;
  22. memcpy(a,b,);
  23. if(on==-){
  24. L inv=pow_mod(n,MOD-);
  25. for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
  26. }
  27. }
  28.  
  29. void fenjie(L n){//分解质因数
  30. for(int i=;i<=;i++)
  31. if(n%i==){
  32. m++; p[m]=i; e[m]=;
  33. while(n%i==) n/=i,d[m]++,e[m]*=i;
  34. }
  35. }
  36. void coushu(int x,L ji){//凑出所有约数
  37. if(x>m) {a[++nn]=ji; return;}
  38. coushu(x+,ji);
  39. for(int i=;i<=d[x];i++){
  40. ji*=p[x];
  41. coushu(x+,ji);
  42. }
  43. }
  44.  
  45. void add(int x,int nk){
  46. L b[];
  47. memcpy(b,f[x],);
  48. for(int i=;i<k;i++)
  49. f[x][i]=(f[x][i]+b[(i-nk+k)%k])%MOD;
  50. f[x][nk]=(f[x][nk]+)%MOD;
  51. }
  52. L w1[]={},w2[]={};
  53. void sub(){
  54. memset(e,,sizeof(e)); memset(d,,sizeof(d));
  55. memset(p,,sizeof(p)); memset(a,,sizeof(a));
  56. memset(f,,sizeof(f)); m=nn=;
  57. cin>>n>>k;
  58. L w=pow_mod(,(MOD-)/k); w1[]=w2[]=;
  59. for(int i=;i<;i++){
  60. w1[i]=w1[i-]*w%MOD;
  61. w2[i]=pow_mod(w1[i],MOD-);
  62. }
  63. m=; fenjie(n);
  64. coushu(,);
  65. for(int i=;i<=nn;i++){
  66. int id=;
  67. for(int j=;j<=m;j++)
  68. if(a[i]%e[j]==) id=id|(<<(j-));
  69. add(id,a[i]%k);
  70. }
  71. int mm=<<m;
  72. for(int i=;i<mm;i++) DFT(f[i],w1,k,);
  73. for(int i=;i<mm;i++)
  74. for(int j=;j<k;j++) f[i][j]++;
  75.  
  76. for(int i=;i<mm;i<<=)
  77. for(int j=;j<mm;j++)
  78. if(i&j){
  79. for(int l=;l<k;l++)
  80. f[j][l]=f[j][l]*f[i^j][l]%MOD;
  81. }
  82. for(int i=;i<mm;i<<=)
  83. for(int j=;j<mm;j++)
  84. if(i&j){
  85. for(int l=;l<k;l++)
  86. f[j][l]=(f[j][l]-f[i^j][l]+MOD)%MOD;
  87. }
  88. DFT(f[mm-],w2,k,-);
  89. printf("%lld\n",f[mm-][]);
  90. }
  91.  
  92. int main(){
  93. int cas; scanf("%d",&cas);
  94. while(cas--) sub();
  95. }

【2018北京集训6】Lcm DFT&FWT的更多相关文章

  1. 【2018北京集训(六)】Lcm

    Portal --> 出错啦qwq(好吧其实是没有) Description 给定两个正整数\(n,k\),选择一些互不相同的正整数,满足这些数的最小公倍数恰好为\(n\),并且这些数的和为\( ...

  2. 【2018北京集训十二】 coin 矩阵快速幂

    矩阵快速幂原来还可以这么用?? 你们城里人还真会玩. 我们令$f[i][j][k]$表示总的钱数为i,当前使用的最大面值硬币的面值为$v_j$,最小为$v_k$的方案数量. 不难发现$f[i][j][ ...

  3. 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)

    牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...

  4. 【北京集训D2T3】tvt

    [北京集训D2T3]tvt \(n,q \le 1e9\) 题目分析: 首先需要对两条路径求交,对给出的四个点的6个lca进行分类讨论.易于发现路径的交就是这六个lca里面最深的两个所形成的链. 然后 ...

  5. (2016北京集训十)【xsy1528】azelso - 概率期望dp

    北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...

  6. 【2017 北京集训 String 改编版】子串

    题意 你有一个字符串,你需要支持两种操作: 1:在字符串的末尾插入一个字符 \(c\) 2:询问当前字符串的 \([l,r]\) 子串中的不同子串个数 为了加大难度,操作会被加密(强制在线). \(n ...

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

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

  8. [2016北京集训试题15]项链-[FFT]

    Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...

  9. 【集训Day4 动态规划】【2018寒假集训 Day4 更新】蛙人

    蛙人 (ple) 蛙人使用特殊设备潜水.设备中有一个气瓶,分两格:一格装氧气,另一格装氮气.留在水中有时间的限制,在深水中需要大量的氧气与氮气.为完成任务,蛙人必须安排好气瓶.每个气瓶可以用它的重量和 ...

随机推荐

  1. 如何通过cmd命令进入到某个硬盘的文件夹

    1.使用快捷键win+R打开运行窗口,并输入cmd回车 2.进入到某个磁盘:在命令提示符中输入d:(代表的的是进入D盘的根目录)并回车 3.接着在cmd中输入dir(dir是directory目录的简 ...

  2. 2018.10.22 cogs2471. [EZOI 2016]源氏的数学课(线段树)

    传送门 线段树入门操作. 直接把题目给的(r−i+1)∗a[i](r-i+1)*a[i](r−i+1)∗a[i]拆开变成(r+1)∗1∗a[i]−i∗a[i](r+1)*1*a[i]-i*a[i](r ...

  3. 2018.07.03 POJ 1279Art Gallery(半平面交)

    Art Gallery Time Limit: 1000MS Memory Limit: 10000K Description The art galleries of the new and ver ...

  4. 马婕 2014年MBA,mpacc备考 报刊宣读1 中国的电子商务(转)

    http://blog.sina.com.cn/s/blog_3e66af4601015fxi.html 中国电子商务蓄势待发 Chinese e-commerce中国电子商务Pity the par ...

  5. SPSS-两变量相关性分析

    两个变量之间存在确定性:关系和不确定关系(会存在一定的波动范围),就好比你的亲生母亲绝对只有一个,而你的亲叔叔可能有好几个(可以在1叔—4叔之间波动) 相关性一般分为   1:强正相关关系  (一个值 ...

  6. Codeforces758B Blown Garland 2017-01-20 10:19 87人阅读 评论(0) 收藏

    B. Blown Garland time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  7. colorbox在android上由于高度太高无法scroll问题

    首先看问题截图: 我们可以看到弹出的colorbox页面的高度已经到了下面,你根本看不到"mistake cross"<=>"X". 我测试了iph ...

  8. Delphi 中 FindWindow 和 FindWindowEx 的语法和用法

    FindWindow(lpClassName,        {窗口的类名}lpWindowName: PChar {窗口的标题}): HWND;              {返回窗口的句柄; 失败返 ...

  9. Delphi XE6 Android拨号函数

    http://blog.sina.com.cn/s/blog_44fa172f0101rpex.html Delphi XE6 Android拨号函数 (2014-05-07 17:48:51) 转载 ...

  10. php类模块引擎PDO操作MySQL数据库简单阐述

    PDO是什么呢? 通俗说就是别人写的一个“数据库操作工具类”,它非常强大,可以应对市面上几乎所有主流数据库, 具体应用时候有这样一个关系: 即,要操作某种数据,就得去“打开”对应的pdo引擎. 在ph ...