有好多好玩的知识点

LOJ

题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模

$ n<=10^9,m<=8000且是质数,集合大小不超过m$


$ Solution:$

我们先考虑改乘积为加和之后怎么做

直接对于集合中的数构建生成函数

所要求的就是这个生成函数的$ n$次幂的所有模$ m$为$ c$的项的系数的和

用快速幂优化这个生成函数的$ n$次幂

每次乘法之后立刻把$ [m,2m)$的系数加回$[0,m)$

这样可以保证每时每刻生成函数的长度不超过$ m$

就可以直接$ NTT$优化这个过程了

时间复杂度为$ O(m log m log n)$

然后考虑乘积的情况

我们知道$ x^ax^b=x^{a+b}$

尝试把每个数改成某个底数的若干次方

由于$ m$是质数一定存在原根

原根有性质是它的$[0,phi(m))$在模$ m$意义下互不相同

这样就可以直接把每个集合中的数改成$ m$的原根的若干次方就好了

然后就是加和情况的做法

复杂度不变

注意可能要特判原集合中存在$ 0$的情况


$ my \ code$

  1. #include<ctime>
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<vector>
  9. #define p 1004535809
  10. #define rt register int
  11. #define ll long long
  12. using namespace std;
  13. inline ll read(){
  14. ll x = ; char zf = ; char ch = getchar();
  15. while (ch != '-' && !isdigit(ch)) ch = getchar();
  16. if (ch == '-') zf = -, ch = getchar();
  17. while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
  18. }
  19. void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
  20. void writeln(const ll y){write(y);putchar('\n');}
  21. int i,j,k,m,n,x,y,z,cnt,c,yg;
  22. int a[],val[];
  23. namespace NTT{
  24. int ksm(int x,int y){
  25. int ans=;
  26. for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*x*ans%p;
  27. return ans;
  28. }
  29. vector<int>R;
  30. void NTT(int n,vector<int>&A,int fla){
  31. A.resize(n);
  32. for(rt i=;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
  33. for(rt i=;i<n;i<<=){
  34. int w=ksm(,(p-)//i);
  35. for(rt j=;j<n;j+=i<<){
  36. int K=;
  37. for(rt k=;k<i;k++,K=1ll*K*w%p){
  38. const int x=A[j+k],y=1ll*K*A[i+j+k]%p;
  39. A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;
  40. }
  41. }
  42. }
  43. if(fla==-){
  44. reverse(A.begin()+,A.end());
  45. int invn=ksm(n,p-);
  46. for(rt i=;i<n;i++)A[i]=1ll*A[i]*invn%p;
  47. }
  48. }
  49. void mul(int del,int n,vector<int>&A){
  50. NTT(n,A,);
  51. for(rt i=;i<n;i++)A[i]=1ll*A[i]*A[i]%p;
  52. NTT(n,A,-);
  53. for(rt i=del;i<n;i++)(A[i%del]+=A[i])%=p,A[i]=;
  54. }
  55. void calc(int n,vector<int>&A,int y,int pl){
  56. int lim=;
  57. while(lim<=n*+)lim<<=;
  58. R.resize(lim);A.resize(lim);
  59. for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|((i&)*(lim>>));
  60. vector<int>ans;ans.resize(lim);
  61. ans[]=;
  62. for(rt i=y;i;i>>=,mul(n,lim,A))if(i&){
  63. NTT(lim,ans,);NTT(lim,A,);
  64. for(rt j=;j<lim;j++)ans[j]=1ll*ans[j]*A[j]%p;
  65. NTT(lim,ans,-);NTT(lim,A,-);
  66. for(rt j=n;j<lim;j++)(ans[j%n]+=ans[j])%=p,(A[j%n]+=A[j])%=p,ans[j]=,A[j]=;
  67. }
  68. writeln((ans[pl]+p)%p);
  69. }
  70. };
  71. vector<int>A,B;
  72. using namespace NTT;
  73. int main(){
  74. n=read();m=read();c=read();k=read();
  75. A.resize(m+);
  76. for(rt i=;i<=m;i++){
  77. for(rt j=,k=i;j<m-;j++,k=1ll*k*i%m)if(k==)goto GG;
  78. yg=i;break;
  79. GG:;
  80. }
  81. for(rt i=,j=;i<m-;i++,j=1ll*yg*j%m)val[j]=i;
  82. for(rt i=;i<=k;i++){
  83. x=read();if(x)A[val[x]]++;
  84. }
  85. calc(m-,A,n,val[c]);
  86. return ;
  87. }

LOJ #2183「SDOI2015」序列统计的更多相关文章

  1. 【LOJ】#2183. 「SDOI2015」序列统计

    题解 这个乘积比较麻烦,转换成原根的指数乘法就相当于指数加和了,可以NTT优化 注意判掉0 代码 #include <bits/stdc++.h> #define fi first #de ...

  2. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  3. loj #2051. 「HNOI2016」序列

    #2051. 「HNOI2016」序列 题目描述 给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na​1​​,a​2​​,⋯,a​n​​,记为 a[1: ...

  4. LOJ 3158: 「NOI2019」序列

    题目传送门:LOJ #3158. 题意简述: 给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \( ...

  5. LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分

    题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...

  6. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

  7. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  8. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  9. Loj 3058. 「HNOI2019」白兔之舞

    Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...

随机推荐

  1. Unable to load script from assets 'index.android.bundle'.make sure you bundle is packaged correctly

    解决此问题 以下方法每次都需要执行命令2才能更新 1.创建assets目录 mkdir android/app/src/main/assets 2.执行命令 react-native bundle - ...

  2. [SDOI2011]计算器(exgcd&BSGS)

    k=1:裸的快速幂k=2:xy=z+kp,直接exgcd,这个可以不用解释了,不懂的同学可以看代码 k=3:裸的BSGS 重点是k=3(BSGS学习)ax=b(mod p)求解这个同余方程只能求gcd ...

  3. 第十五节、韦伯局部描述符(WLD,附源码)

    纹理作为一种重要的视觉线索,是图像中普遍存在而又难以描述的特征,图像的纹理特征一般是指图像上地物重复排列造成的灰度值有规则的分布.纹理特征的关键在于纹理特征的提取方法.目前,用于纹理特征提取的方法有很 ...

  4. python自动化开发-[第二十五天]-scrapy进阶与flask使用

    今日内容概要 1.cookie操作 2.pipeline 3.中间件 4.扩展 5.自定义命令 6.scrapy-redis 7.flask使用 - 路由系统 - 视图 - 模版 - message( ...

  5. bzoj1009 KMP+矩阵dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(<=Xi<=), ...

  6. Java基础super关键字、final关键字、static关键字、匿名对象整理

    super关键字 10.1子父类中构造方法的调用 public class Test { public static void main(String[] args) { new Zi(); } } ...

  7. linux中文件多行合并为一行的例子

    现网中经常遇到匹配到某一关键字下的所有行合并到同一行,再次匹配到相关关键字再和下面的合并,示例如下: # line1ab# line2cde# line3f想要变成: # line1 a b# lin ...

  8. Hbase学习03

    第3章 Hbase数据存储模型与工作组件 Data格式设计的的总体原则是按照需求要求,依据Hbase性能的相关标准规范和文件,并遵循“统一规范.统一数据模型.统一规划集群.分步实施”的原则,注重实际应 ...

  9. SpringBoot笔记十一:html通过Ajax获取后端数据

    我们知道在Java Web中,前端的JSP可以使用EL表达式来获取Servlet传过来的数据Spring Boot中也有Thymeleaf模板可以使用th: text="${XXX}&quo ...

  10. Jquery 添加插件

    原文:http://www.iteye.com/topic/545971 jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法 ...