还是没有理解透原根……题目提示其实挺明显的,M是质数,然后1<=x<=M-1

这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法

首先因为0和任何数乘都是0,和其他数规则不相符,所以不考虑(答案也没让求)

然后看原根的性质,设g是M的原根,那么\( g^i%M 0<=i<M-1 \)就是1~M-1的不重集合,所以可以把乘法变成原根指数的加法,这样就变成多项式乘法了,可以用NTT优化

然后n非常大,所以使用快速幂进行多项式乘法

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. const int N=20005,mod=1004535809,g=3;
  6. int n,m,x,k,s[N],d=2,id[N],lm,bt,re[N];
  7. long long a[N],c[N],r[N];
  8. int read()
  9. {
  10. int r=0,f=1;
  11. char p=getchar();
  12. while(p>'9'||p<'0')
  13. {
  14. if(p=='-')
  15. f=-1;
  16. p=getchar();
  17. }
  18. while(p>='0'&&p<='9')
  19. {
  20. r=r*10+p-48;
  21. p=getchar();
  22. }
  23. return r*f;
  24. }
  25. void jia(long long &x,long long &y)
  26. {
  27. x+=y;
  28. x>=mod?x-=mod:0;
  29. }
  30. long long ksm(long long a,long long b,int mod)
  31. {
  32. long long r=1;
  33. while(b)
  34. {
  35. if(b&1)
  36. r=r*a%mod;
  37. a=a*a%mod;
  38. b>>=1;
  39. }
  40. return r;
  41. }
  42. void dft(long long a[],int f)
  43. {
  44. for(int i=0;i<lm;i++)
  45. if(i<re[i])
  46. swap(a[i],a[re[i]]);
  47. for(int i=1;i<lm;i<<=1)
  48. {
  49. long long wi=ksm(g,(mod-1)/(2*i),mod);
  50. if(f==-1)
  51. wi=ksm(wi,mod-2,mod);
  52. for(int k=0;k<lm;k+=(i<<1))
  53. {
  54. long long w=1,x,y;
  55. for(int j=0;j<i;j++)
  56. {
  57. x=a[j+k],y=1ll*w*a[i+j+k]%mod;
  58. a[j+k]=((x+y)%mod+mod)%mod,a[i+j+k]=((x-y)%mod+mod)%mod;
  59. w=w*wi%mod;
  60. }
  61. }
  62. }
  63. if(f==-1)
  64. {
  65. long long inv=ksm(lm,mod-2,mod);
  66. for(int i=0;i<lm;i++)
  67. a[i]=a[i]*inv%mod;
  68. }
  69. }
  70. void ntt(long long a[],long long b[])
  71. {
  72. for(int i=0;i<lm;i++)
  73. c[i]=b[i];
  74. dft(a,1);
  75. dft(c,1);
  76. for(int i=0;i<lm;i++)
  77. a[i]=a[i]*c[i]%mod;
  78. dft(a,-1);
  79. for(int i=m-1;i<lm;i++)
  80. jia(a[i%(m-1)],a[i]),a[i]=0;
  81. // for(int i=0;i<lm;i++)
  82. // cerr<<a[i]<<" ";cerr<<endl;
  83. }
  84. int main()
  85. {
  86. n=read()-1,m=read(),x=read(),k=read();
  87. for(int i=1;i<=k;i++)
  88. s[i]=read();
  89. for(bool fl=0;!fl;d++)
  90. {
  91. fl=1;
  92. for(int i=1;i<m-1;i++)
  93. if(ksm(d,i,m)==1)
  94. {
  95. fl=0;
  96. break;
  97. }
  98. if(ksm(d,m-1,m)!=1)
  99. fl=0;
  100. if(fl)
  101. break;
  102. }
  103. for(int i=0;i<m-1;i++)
  104. id[ksm(d,i,m)]=i;//,cerr<<rl[i]<<" "<<i<<endl;
  105. for(int i=1;i<=k;i++)
  106. if(s[i])
  107. a[id[s[i]]]++,r[id[s[i]]]++;
  108. for(bt=0;(1<<bt)<=2*m;bt++);
  109. lm=(1<<bt);
  110. for(int i=0;i<lm;i++)
  111. re[i]=(re[i>>1]>>1)|((i&1)<<(bt-1));
  112. while(n)
  113. {
  114. if(n&1)
  115. ntt(r,a);
  116. ntt(a,a);
  117. n>>=1;
  118. }
  119. printf("%lld\n",r[id[x]]);
  120. return 0;
  121. }

bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】的更多相关文章

  1. 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)

    传送门 生成函数简单题. 题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1​,a2​,...as​},所有数都在[0,m−1][0,m-1][0,m− ...

  2. BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】

    题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...

  3. BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1017  Solved: 466[Submit][Statu ...

  4. BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1155  Solved: 532[Submit][Statu ...

  5. BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)

    3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...

  6. [BZOJ 3992][SDOI2015]序列统计

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 2275  Solved: 1090[Submit][Stat ...

  7. BZOJ.3992.[SDOI2015]序列统计(DP NTT 原根)

    题目链接 \(Description\) 给定\(n,m,x\)和集合\(S\).求\(\prod_{i=1}^na_i\equiv x\ (mod\ m)\)的方案数.其中\(a_i\in S\). ...

  8. bzoj 3992 [SDOI2015]序列统计——NTT(循环卷积&&快速幂)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有转移次数.模M余数.方案数三个值,一看就是系数的地方放一个值.指数的地方放一个值.做 ...

  9. bzoj 3992 [SDOI2015] 序列统计 —— NTT (循环卷积+快速幂)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 (学习NTT:https://riteme.github.io/blog/2016-8 ...

随机推荐

  1. css设置背景图片自适应

      CreateTime--2017年12月25日16:36:07 Author:Marydon 控制背景图片100%自适应填充布局 /* 控制背景图片100%自适应填充布局 */ body{ bac ...

  2. Yii框架中安装srbac扩展方法

    首先,下载srbac_1.3beta.zip文件和对应的blog-srbac_1.2_r228.zip 问什么要下载第二个文件,后面就知道了. 按照手册进行配置: 解压缩srbac_1.3beta.z ...

  3. addEventListener event

    addEventListener   先看个例子: document.getElementById("myBtn").addEventListener("click&qu ...

  4. CSDN-markdown编辑器之从线上导入Markdown文件

      CSDN-markdown编辑器支持从线上导入Markdown文件的功能,假设你用其他支持Markdown的编辑器在网上写了博客文章或说明档,想公布到CSDN博客中,就能够使用本功能非常方便的完毕 ...

  5. 程序员笔记|如何编写高性能的Java代码

    一.并发 Unable to create new native thread …… 问题1:Java中创建一个线程消耗多少内存? 每个线程有独自的栈内存,共享堆内存 问题2:一台机器可以创建多少线程 ...

  6. 【读书笔记】iOS-GCD-用法

    代码: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { dispatch_async(dispatch_get_gl ...

  7. junit使用小结

    1.spring中使用 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=CDPlayerConfig.cla ...

  8. 一个简单的servlet

    1.创建一个自己的servlet文件,继承HttpServlet MyServlet.java package com.jmu.ccjoin.controller; import java.io.IO ...

  9. Hibernate写hql语句与不写hql语句的区别?

    写hql语句与不写hql语句的区别? 写hql语句:书写HQL语句,所有的查询与投影的设计均使用HQL语句完成. 不写hql语句:没有任何查询语句,所有的查询与投影的设计使用面向对象格式完成. 二者选 ...

  10. [原创]java合并word文件

    需求背景 在互联网教育行业,做内容相关的项目经常碰到的一个问题就是如何动态生成一张word试卷.事先把题库中的每一道试题都已经保存成一个独立的word文件了,但是在选择了部分试题生成一张word试卷的 ...