题目描述

好神仙啊,我还真的以为这是个构造题,结果是有唯一解的。

设答案为多项式\(a,a_i\in\{0,1\}\)。

则:

\[f(x)=\Pi (\frac{1}{1-x^i})^{a_i}
\]

两边取对数:

\[\begin{align}
ln(f(x))&=\sum a_i ln(\frac{1}{1-x^i})
\\&=-\sum a_iln(1-x^i)
\end{align}
\]

我们在对\(ln(x)\)在\(x=1\)处进行泰勒展开。

由:

\[\begin{align}
ln(x)&=\sum_{i=0}^{\infty}\frac{ln^{[i]}(x_0)}{i!}(x-x_0)^i\\
&=\sum_{i=1}^{\infty}(-1)^{i-1}\frac{1}{i}(x-1)^i
\end{align}
\]

得到:

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

所以:

\[\begin{align}
ln(f(x))&=-\sum a_i \sum_{j=1}^{\infty}(-1)\frac{x^{ij}}{j}
\\&=\sum_{i=1}^n x^i\sum_{j|i}a_j\frac{j}{i}
\\&=\sum_{i=1}^n\frac{x^i}{i}\sum_{j|i}a_jj
\end{align}
\]

求出\(ln(f(x))\)后就可以用\(nlogn\)的复杂度求出\(a\)了。

因为是任意模数,所以要写\(MTT\)。

推导很自然,思路很巧妙啊。关键是要想到列出关于答案数组\(a\)的等式再去将\(a\)解出来。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  4. typedef long long ll;
  5. const int N=(1<<19);
  6. const ll sqr=1<<15;
  7. ll mod;
  8. ll a[N<<2];
  9. struct Com {
  10. double r,v;
  11. Com() {r=0,v=0;}
  12. Com(double a,double b) {r=a,v=b;}
  13. };
  14. Com operator *(const Com &a,const Com &b) {return Com(a.r*b.r-a.v*b.v,a.r*b.v+a.v*b.r);}
  15. Com operator /(const Com &a,const double &y) {return Com(a.r/y,a.v/y);}
  16. Com operator +(const Com &a,const Com &b) {return Com(a.r+b.r,a.v+b.v);}
  17. Com operator -(const Com &a,const Com &b) {return Com(a.r-b.r,a.v-b.v);}
  18. Com w[N<<2];
  19. const double pi=acos(-1);
  20. void FFT(Com *a,int d,int flag) {
  21. static int rev[N<<2];
  22. int n=1<<d;
  23. for(int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<d-1);
  24. for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
  25. for(int i=0;i<n;i++) w[i]=Com(cos(2*flag*i*pi/n),sin(2*flag*i*pi/n));
  26. for(int s=1;s<=d;s++) {
  27. int len=1<<s,mid=len>>1;
  28. for(int i=0;i<n;i+=len) {
  29. for(int j=0;j<mid;j++) {
  30. Com u=a[i+j],v=a[i+j+mid]*w[n/len*j];
  31. a[i+j]=u+v;
  32. a[i+j+mid]=u-v;
  33. }
  34. }
  35. }
  36. if(flag==-1) for(int i=0;i<n;i++) a[i]=a[i]/n;
  37. }
  38. Com f1[N<<2],f2[N<<2],g1[N<<2],g2[N<<2];
  39. Com A[N<<2],B[N<<2],C[N<<2],D[N<<2];
  40. void mul(ll *f,ll *g,int d,ll *ans) {
  41. int n=1<<d;
  42. for(int i=0;i<n;i++) {
  43. f1[i]=Com(f[i]/sqr,0),f2[i]=Com(f[i]%sqr,0);
  44. g1[i]=Com(g[i]/sqr,0),g2[i]=Com(g[i]%sqr,0);
  45. }
  46. for(int i=0;i<n<<1;i++) ans[i]=0;
  47. for(int i=n;i<n<<1;i++) f1[i]=f2[i]=g1[i]=g2[i]=Com(0,0);
  48. FFT(f1,d+1,1),FFT(f2,d+1,1),FFT(g1,d+1,1),FFT(g2,d+1,1);
  49. for(int i=0;i<n<<1;i++) {
  50. A[i]=f1[i]*g1[i];
  51. B[i]=f1[i]*g2[i];
  52. C[i]=f2[i]*g1[i];
  53. D[i]=f2[i]*g2[i];
  54. }
  55. FFT(A,d+1,-1),FFT(B,d+1,-1),FFT(C,d+1,-1),FFT(D,d+1,-1);
  56. for(int i=0;i<n;i++) ans[i]=(ll(A[i].r+0.5)*sqr%mod*sqr%mod+ll(B[i].r+0.5)*sqr+ll(C[i].r+0.5)*sqr+ll(D[i].r+0.5))%mod;
  57. for(int i=n;i<n<<1;i++) ans[i]=0;
  58. }
  59. ll ksm(ll t,ll x) {
  60. ll ans=1;
  61. for(;x;x>>=1,t=t*t%mod)
  62. if(x&1) ans=ans*t%mod;
  63. return ans;
  64. }
  65. int n,m;
  66. ll tem[N<<2];
  67. void inverse(ll *a,ll *f,int len) {
  68. if(len==1) {return f[0]=ksm(a[0],mod-2),void();}
  69. int d=ceil(log2(len));
  70. inverse(a,f,len>>1);
  71. mul(a,f,d,tem);
  72. mul(tem,f,d,tem);
  73. for(int i=0;i<len;i++) f[i]=(2*f[i]-tem[i]+mod)%mod;
  74. }
  75. ll inv[N<<2];
  76. void Ln(ll *a,ll *ans,int len) {
  77. for(int i=0;i<len-1;i++) ans[i]=a[i+1]*(i+1)%mod;
  78. int d=ceil(log2(len));
  79. inverse(a,inv,len);
  80. ans[len-1]=0;
  81. mul(ans,inv,d,ans);
  82. for(int i=len-1;i;i--) ans[i]=ans[i-1]*ksm(i,mod-2)%mod;
  83. ans[0]=0;
  84. }
  85. ll f[N<<2];
  86. int main() {
  87. n=Get(),mod=Get();
  88. for(int i=1;i<=n;i++) a[i]=Get();
  89. a[0]=1;
  90. int d=ceil(log2(n+1));
  91. Ln(a,f,1<<d);
  92. for(int i=1;i<=n;i++) f[i]=f[i]*i%mod;
  93. int tot=0;
  94. for(int i=1;i<=n;i++) {
  95. for(int j=i+i;j<=n;j+=i) {
  96. f[j]=(f[j]-f[i]+mod)%mod;
  97. }
  98. if(f[i]) tot++;
  99. }
  100. cout<<tot<<"\n";
  101. for(int i=1;i<=n;i++) if(f[i]) cout<<i<<" ";
  102. return 0;
  103. }

【SDOI2017】遗忘的集合的更多相关文章

  1. [SDOI2017]遗忘的集合

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

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

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

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

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

  4. [题解] LuoguP3784 [SDOI2017]遗忘的集合

    要mtt的题都是...... 多补了几项就被卡了一整页......果然还是太菜了...... 不说了......来看100分的做法吧...... 如果做过付公主的背包,前面几步应该不难想,所以我们再来 ...

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

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

  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. SDOI2017遗忘的集合

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

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

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

随机推荐

  1. SpringBoot 2.0 报错: Failed to configure a DataSource: 'url' attribute is not specified and no embe

    问题描述 *************************** APPLICATION FAILED TO START *************************** Description ...

  2. Base64字符保存图片,图片转换成Base64字符编码

    //文件转换成Base64编码 public static String getFileBase64Str(String filePath) throws IOException { String f ...

  3. Hibernate入门(十二)离线条件检索

    Hibernate——离线条件检索DetachedCriteria DetachedCriteria翻译为离线条件查询,因为它是可以脱离Session来使用的一种条件查询对象,我们都知道Criteri ...

  4. confidence interval

    95%置信区间.置信区间的两端被称为置信极限.对一个给定情形的估计来说,置信水平越高,所对应的置信区间就会越大. 对置信区间的计算通常要求对估计过程的假设(因此属于参数统计),比如说假设估计的误差是成 ...

  5. Laravel篇二之本地版本库关联github

    以往的工作中都是使用svn作为版本控制,对git分布式的有些陌生,本篇主要记录的本地存储myWeb-laravel的git版本库与github建立关联. 1.首先进入本地myWeb-laravel,执 ...

  6. cloudera manager 安装配置

    前面cloudera manager 环境准备和安装我参考的是: https://blog.csdn.net/m0_38017084/article/details/82218559 这篇博客,写的非 ...

  7. PlugNT CMS v4.6.3 调用文章上一页和下一页及点击数加1

    using System; using System.Data; using System.Web; using System.Web.UI; using System.Web.UI.WebContr ...

  8. SuperMap iClient for JavaScript image出图

    SuperMap iClient for JavaScript 客户端基于openlayers 开发. 目前最高版本为811,9D产品后推荐客户使用leaflet.openlayers客户端开发. 问 ...

  9. Linux网络编程--socket

    1.socket的核心思想是,作为服务器间的进程间通信的最底层的实现,常用的大部分网络协议都是基于socket实现. 2.socket 是如何与最终的低层收发包建立联系的? 3.socket 是如何与 ...

  10. viewPager+fragment如何刷新缓存fragment

    最近在做一个项目,有一个功能是答题翻页.于是需要实现在这一页的时候就缓存下一页. 刚刚开始我是用 setOnPageChangeListener方法监听,滑到这一页的时候才刷新这一页: public ...