要mtt的题都是......

多补了几项就被卡了一整页......果然还是太菜了......


不说了......来看100分的做法吧......

如果做过付公主的背包,前面几步应该不难想,所以我们再来写一遍柿子。

首先令\(c_i = [0,1]\)表示数\(i\)是否在集合中,那么\(f\)的生成函数就是

\[F(x) = \prod\limits_{i=1}^n (\frac{1}{1-x^i})^{c_i}
\]

乘法不太好做,我们两边\(\ln\)一下,转化成加法

\[\ln F(x) = \sum\limits_{i=1}^n c_i \ln(\frac{1}{1-x^i})
\]

我们想要右边的\(\ln\)变得好看一点,这个柿子在付公主的背包里好像推过了......这里就不写了。

柿子是

\[\ln(\frac{1}{1-x^i}) = \sum\limits_{j=1}^{\infty}\frac{1}{j}x^{ij}
\]

带上去再做一些变化

\[\ln F(x) = \sum\limits_{i=1}^n c_i \sum\limits_{j \ge 1} \frac{1}{j} x^{ij}
\]

我们枚举\(k = ij\)

\[\ln F(x) = \sum\limits_{k=1}^n x^k \sum\limits_{i \mid k} c_i\cdot \frac{i}{k}
\]

我们令\(f'_k\)表示\(\ln F(x)\)的\(i\)次项系数\(\times k\),知道了\(f'_k = \sum\limits_{i \mid k} c_i i\)

那么我们要构造一组\(c\),使得答案的字典序最小。字典序这个东西有很强的可贪性......

我们肯定会先考虑较小的\(i\),然后我们又知道对于能被\(i\)整除的\(j\),也就是\(i \mid j\),有\(f'_j \ge f'_i\),因为能对\(i\)产生贡献的\(c_k\),对\(j\)也会产生贡献。

所以当我们把\(f'\)求出来的时候,做一个类似筛法的东西,\(\forall j, i\mid j\),让\(f'_j\)减\(f'_i\)。

最后剩下类非\(0\)的\(f'_i\),\(i\)就是在一个集合内的数,这样复杂度是对的。

然而需要MTT,异常duliu......

得到了一个教训......代码中的limit不可以瞎开......

\(Code:\)(只会写辣鸡版本的MTT......)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long double db;
  4. typedef long long ll;
  5. const db PI=acos(-1.0);
  6. const int N=8e5+10;
  7. int mod;
  8. inline int fpow(int x,int y){
  9. int ret=1; for(x%=mod;y;y>>=1,x=1ll*x*x%mod)
  10. if(y&1) ret=1ll*ret*x%mod;
  11. return ret;
  12. }
  13. inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
  14. inline int sub(int x,int y){return x-y<0?x-y+mod:x-y;}
  15. namespace Poly{
  16. struct cpl{
  17. db x,y;
  18. cpl operator + (cpl k1)const{return (cpl){x+k1.x,y+k1.y};}
  19. cpl operator - (cpl k1)const{return (cpl){x-k1.x,y-k1.y};}
  20. cpl operator * (cpl k1)const{return (cpl){x*k1.x-y*k1.y,x*k1.y+y*k1.x};}
  21. };
  22. int rev[N];
  23. void init(int n){
  24. for(int i=0;i<n;i++)
  25. rev[i]=rev[i>>1]>>1|((i&1)?n>>1:0);
  26. }
  27. void fft(cpl *f,int n,int flg){
  28. for(int i=0;i<n;i++) if(rev[i]<i) swap(f[i],f[rev[i]]);
  29. for(int len=2,k=1;len<=n;len<<=1,k<<=1){
  30. cpl wn=(cpl){cos(2*PI/len),flg*sin(2*PI/len)};
  31. for(int i=0;i<n;i+=len){
  32. cpl w=(cpl){1,0};
  33. for(int j=i;j<i+k;j++,w=w*wn){
  34. cpl tmp=w*f[j+k];
  35. f[j+k]=f[j]-tmp,f[j]=f[j]+tmp;
  36. }
  37. }
  38. }
  39. if(flg==-1) for(int i=0;i<n;i++)
  40. f[i].x/=n;
  41. }
  42. void mtt(int *a,int *b,int *c,int n){
  43. static cpl f[2][N],g[2][N],ans[3][N];
  44. for(int i=0;i<n;i++){
  45. f[0][i]=(cpl){(db)(a[i]>>15),0};
  46. f[1][i]=(cpl){(db)(a[i]&0x7fff),0};
  47. g[0][i]=(cpl){(db)(b[i]>>15),0};
  48. g[1][i]=(cpl){(db)(b[i]&0x7fff),0};
  49. }
  50. fft(f[0],n,1),fft(f[1],n,1),fft(g[0],n,1),fft(g[1],n,1);
  51. for(int i=0;i<n;i++){
  52. ans[0][i]=f[0][i]*g[0][i];
  53. ans[1][i]=f[0][i]*g[1][i]+f[1][i]*g[0][i];
  54. ans[2][i]=f[1][i]*g[1][i];
  55. }
  56. fft(ans[0],n,-1),fft(ans[1],n,-1),fft(ans[2],n,-1);
  57. #define normal(x) (((ll)((x)+0.5)%mod+mod)%mod)
  58. for(int i=0;i<n;i++){
  59. ll t1=(normal(ans[0][i].x)<<30ll)%mod;
  60. ll t2=(normal(ans[1][i].x)<<15ll)%mod,t3=normal(ans[2][i].x);
  61. c[i]=((t1+t2)%mod+t3)%mod;
  62. }
  63. }
  64. void dao(int *f,int n,int *G){
  65. static int F[N]; for(int i=0;i<=n;i++) F[i]=f[i];
  66. for(int i=1;i<=n;i++) G[i-1]=1ll*F[i]*i%mod; G[n]=0;
  67. }
  68. void jifen(int *f,int n,int *G){
  69. static int F[N]; for(int i=0;i<=n;i++) F[i]=f[i];
  70. for(int i=0;i<=n;i++) G[i+1]=1ll*F[i]*fpow(i+1,mod-2)%mod; G[0]=0;
  71. }
  72. void getinv(int *f,int n,int *G){
  73. if(n==1){G[0]=fpow(f[0],mod-2);return;}
  74. getinv(f,(n+1)>>1,G);
  75. static int F[N],H[N],H1[N];
  76. int limit=1; while(limit<=(n-1)*2)limit<<=1; init(limit);
  77. for(int i=0;i<n;i++) H[i]=G[i],F[i]=f[i];
  78. for(int i=n;i<limit;i++) H[i]=F[i]=G[i]=0;
  79. mtt(F,G,H1,limit);
  80. H1[0]=sub(2,H1[0]);
  81. for(int i=1;i<limit;i++) H1[i]=i<n?mod-H1[i]:0;
  82. for(int i=n;i<limit;i++) H1[i]=0;
  83. mtt(H,H1,G,limit);
  84. for(int i=n;i<limit;i++) G[i]=0;
  85. }
  86. void getln(int *f,int n,int *G){
  87. static int F[N],iF[N]; for(int i=0;i<n;i++) F[i]=f[i];
  88. getinv(F,n,iF),dao(F,n-1,F);
  89. int limit=1; while(limit<=(n-1)*2)limit<<=1; init(limit);
  90. mtt(F,iF,G,limit);
  91. jifen(G,n-1,G); for(int i=n;i<limit;i++) G[i]=0;
  92. }
  93. }
  94. int n,f[N],ans[N];
  95. int main(){
  96. scanf("%d%d",&n,&mod);
  97. f[0]=1; for(int i=1;i<=n;i++) scanf("%d",&f[i]);
  98. Poly::getln(f,n+1,ans);
  99. for(int i=1;i<=n;i++) ans[i]=1ll*ans[i]*i%mod;
  100. for(int i=1;i<=n;i++)
  101. for(int j=i*2;j<=n;j+=i) ans[j]=sub(ans[j],ans[i]);
  102. int cnt=0;
  103. for(int i=1;i<=n;i++) if (ans[i]) ++cnt;
  104. printf("%d\n",cnt);
  105. for(int i=1;i<=n;i++) if(ans[i]) printf("%d ",i);
  106. return 0;
  107. }

[题解] LuoguP3784 [SDOI2017]遗忘的集合的更多相关文章

  1. [SDOI2017]遗忘的集合

    [SDOI2017]遗忘的集合 综合了很多套路的题 一看就是完全背包 生成函数! 转化为连乘积形式 Pi....=F 求Ln! 降次才可以解方程 发现方程是: f[i]=∑t|i : bool(t)* ...

  2. 洛谷P3784 [SDOI2017]遗忘的集合(生成函数)

    题面 传送门 题解 生成函数这厮到底还有什么是办不到的-- 首先对于一个数\(i\),如果存在的话可以取无限多次,那么它的生成函数为\[\sum_{j=0}^{\infty}x^{ij}={1\ove ...

  3. [BZOJ4913][SDOI2017]遗忘的集合

    题解: 首先先弄出$f(x)$的生成函数$$f(x)=\prod_{i=1}^{n} {{(\frac{1}{1-x^i})}}^{a[i]}$$因为$f(x)$已知,我们考虑利用这个式子取推出$a[ ...

  4. [LOJ2271] [SDOI2017] 遗忘的集合

    题目链接 LOJ:https://loj.ac/problem/2271 洛谷:https://www.luogu.org/problemnew/show/P3784 BZOJ太伤身体死活卡不过还是算 ...

  5. SDOI2017遗忘的集合

    题面链接 咕咕咕 题外话 为了这道题我敲了\(MTT\).多项式求逆.多项式\(ln\)等模板,搞了将近一天. sol 最近懒得写题解啊,随便搞搞吧. 看到这个就是生成函数套上去. \[F(x)=\p ...

  6. P3784 [SDOI2017]遗忘的集合

    非常神仙的一道题! 题意:给出某n个数字跑完全背包m容量的dp数组,求满足要求的字典序最小的n个元素,不知道n是多少. 首先考虑付公主的背包这个题. 对dp数组求一个ln,设它为F. 已知 e^(G1 ...

  7. 洛谷 3784(bzoj 4913) [SDOI2017]遗忘的集合——多项式求ln+MTT

    题目:https://www.luogu.org/problemnew/show/P3784 https://www.lydsy.com/JudgeOnline/problem.php?id=4913 ...

  8. BZOJ 4913 [Sdoi2017] 遗忘的集合

    骂了隔壁的 BZOJ垃圾评测机 我他妈卡了两页的常数了 我们机房的电脑跑的都比BZOJ快

  9. 【题解】LOJ2462完美的集合(树DP 魔改Lucas)

    [题解]LOJ2462完美的集合(树DP 魔改Lucas) 省选模拟考这个??????????????????? 题目大意: 有一棵树,每个点有两个属性,一个是重量\(w_i\)一个是价值\(v_i\ ...

随机推荐

  1. 【剑指Offer面试编程题】题目1372:最大子向量和--九度OJ

    题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但 ...

  2. P1095 解码PAT准考证

    1095 解码PAT准考证 (25分)   PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级:A 代表甲级:B 代表乙级: 第 2~4 位是考场编号,范围从 101 到 999: ...

  3. 新闻网大数据实时分析可视化系统项目——5、Hadoop2.X HA架构与部署

    1.HDFS-HA架构原理介绍 hadoop2.x之后,Clouera提出了QJM/Qurom Journal Manager,这是一个基于Paxos算法实现的HDFS HA方案,它给出了一种较好的解 ...

  4. layui-简单的登录注册界面

    register.html 源代码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  5. 剑指offer 把数组排成最小的数 atoi和itoa,pow

    pow(x,y)在#include<math.h>文件中,计算x的y次方. C++引入头文件:#include <stdlib.h> 或者 #include <cstdl ...

  6. Unity 公告板 Billboard

    创建脚本如下 Billboard.cs using UnityEngine; using System.Collections; public class Billboard : MonoBehavi ...

  7. POJ - 1061 青蛙的约会 (扩展欧几里得求同余式)

    题意:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对 ...

  8. BGR to RGB排列

    BGR to RGB排列 2012年09月27日 13:59:48 雷电羊 阅读数:4759   https://blog.csdn.net/cjsycyl/article/details/80247 ...

  9. maze-----攻防世界

    题目下载之后在linux上查看一下 发现是elf文件尝试运行一下: 要求输入正确的flag才可以,ida查看 交叉引用 对长度和开头对比,进行判断. 转到400690查看 和#进行比较,hex 是一个 ...

  10. Windows使用Nexus搭建Maven私服

    简介 Maven私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件,有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库,否则,私服请求外部的 ...