【BZOJ3992】【SDOI2015】序列统计 EGF+多项式快速幂+循环卷积
如果是求$n$个数之和在模$m$意义下为$x$,那么做法是显然的。
但是这道题问的是$n$个数之积在模m意义下为$x$,那么做法就和上面的问题不同。
考虑如何把乘法转换成加法(求log):
题目中有一个很特殊的条件:$m$是个质数。
不妨假设$m$的原根为$g$。那么显然,我们可以用$g^x%m$构造出$[0,m)$中的所有数。
那么对于两个数$A$和$B$,我们将它变形为$g^{x_1}$和$g^{x_2}$,那么$A \times B=g^{x_1+x_2}$。
我们构造一个m-1次多项式A,对于A的第i项,A_i=$\begin{equation} \left\{ \begin{array}{lr} 1 \ [x^i \equiv k(mod\ m),\ k∈S].\\0 \end{array} \right. \end{equation}$。
然后,不妨设读入的$X=g^k$,则答案即为$[x^k]A^n(x)$,注意这里的卷积是循环卷积。
然后就没了,注意S中出现0的情况。
#include<bits/stdc++.h>
#define M 32768
#define MOD 1004535809
#define G 3
#define L long long
using namespace std; L pow_mod(L x,L k){
L ans=;
while(k){
if(k&) ans=ans*x%MOD;
x=x*x%MOD; k>>=;
}
return ans;
} void change(L a[],int n){
for(int i=,j=;i<n-;i++){
if(i<j) swap(a[i],a[j]);
int k=n>>;
while(j>=k) j-=k,k>>=;
j+=k;
}
}
void NTT(L a[],int n,int on){
change(a,n);
for(int h=;h<=n;h<<=){
L wn=pow_mod(G,(MOD-)/h);
for(int j=;j<n;j+=h){
L w=;
for(int k=j;k<j+(h>>);k++){
L u=a[k],t=a[k+(h>>)]*w%MOD;
a[k]=(u+t)%MOD;
a[k+(h>>)]=(u-t+MOD)%MOD;
w=w*wn%MOD;
}
}
}
if(on==-){
L inv=pow_mod(n,MOD-);
for(int i=;i<n;i++) a[i]=a[i]*inv%MOD;
reverse(a+,a+n);
}
}
L a[M]={},b[M]={},ans[M]={};
int gn[M]={},g=,vis[M]={}; void get(int n){
for(int i=;i<n;i++){
memset(vis,,n<<);
vis[]=; gn[]=;
int hh=,ok=;
for(int j=;j<n-;j++){
hh=hh*i%n;
if(vis[hh]){ok=; break;}
vis[hh]=; gn[hh]=j;
}
if(ok){g=i; return;}
}
} int main(){
int n,m,x,s,nn=;
scanf("%d%d%d%d",&n,&m,&x,&s);
while(nn<(m*)) nn<<=;
get(m);
for(int i=;i<s;i++){
int x; scanf("%d",&x);
if(x==) continue;
x=gn[x];
a[x]++;
}
ans[]=; m--;
while(n){
if(n&){
NTT(a,nn,); NTT(ans,nn,);
for(int i=;i<nn;i++) ans[i]=ans[i]*a[i]%MOD;
NTT(a,nn,-); NTT(ans,nn,-);
for(int i=;i<m;i++) ans[i]=(ans[i]+ans[i+m])%MOD;
for(int i=m;i<nn;i++) ans[i]=;
}
NTT(a,nn,);
for(int i=;i<nn;i++) a[i]=a[i]*a[i]%MOD;
NTT(a,nn,-);
for(int i=;i<m;i++) a[i]=(a[i]+a[m+i])%MOD;
for(int i=m;i<nn;i++) a[i]=;
n>>=;
}
printf("%lld\n",ans[gn[x]]);
}
【BZOJ3992】【SDOI2015】序列统计 EGF+多项式快速幂+循环卷积的更多相关文章
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
		
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
 - LOJ 2183 / SDOI2015 序列统计 (DP+矩阵快速幂)
		
题面 传送门 分析 考虑容斥原理,用总的方案数-不含质数的方案数 设\(dp1[i][j]\)表示前i个数,和取模p为j的方案数, \(dp2[i][j]\)表示前i个数,和取模p为j的方案数,且所有 ...
 - [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
		
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1888 Solved: 898[Submit][Statu ...
 - BZOJ3992: [SDOI2015]序列统计
		
Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列. ...
 - 【NTT】bzoj3992: [SDOI2015]序列统计
		
板子题都差点不会了 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生 ...
 - 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− ...
 - BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)
		
题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...
 - BZOJ3992 [SDOI2015]序列统计  【生成函数 + 多项式快速幂】
		
题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...
 - 【动态规划】bzoj3992 [Sdoi2015]序列统计 10分
		
#include<cstdio> using namespace std; #define MOD 1004535809 int a[8001],f[1001][101],n,m,x,S; ...
 
随机推荐
- Android 在一个程序中启动另一个程序(包名,或者类名)
			
http://hi.baidu.com/xiaofanqing/item/6fd724f7c5bb6dce531c26b7 Android 开发有时需要在一个应用中启动另一个应用,比如Launcher ...
 - 2018.09.01 独立集(树形dp)
			
描述 给定一颗树(边权为1),选取一个节点子集,使得该集合中任意两个节点之间的距离都大于K.求这个集合节点最多是多少 输入 第一行是两个整数N,K 接下来是N-1行,每行2个整数x,y,表示x与y有一 ...
 - 2018.07.22 洛谷P2986 伟大的奶牛聚集(树形dp)
			
传送门 给出一棵树,树有边权和点权,若选定一个点作为中心,这棵树的代价是所有点权乘上到根的距离的和.求代价最小. 解法:一道明显的换根dp" role="presentation& ...
 - 初探Java反射机制
			
反射库提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵java代码的程序库.这项功能被大量地应用于JavaBeans中.反射机制提供了在运行状态中获得和调用修改任何一个类的属性和方法的能力. ...
 - =default(c++11)
			
1.概念 1)如果我们需要编译器默认的行为,则可以在参数列表后面加上=default来显式地要求编译器生成合成版本的默认构造函数和拷贝控制成员:合成的默认构造函数.合成拷贝构造函数.合成拷贝赋值运算符 ...
 - Spring 获取资源文件路径
			
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; s ...
 - MFC框架仿真<三>R T T I
			
RTTI,简单的说,就是判定A类是否为B类的基类.将书本的内容最大程度的简化,如下图的类层次,现在解决的问题就是:判定“梨”是否是“红富士”的基类.
 - (博弈)Simple Game --codeforces--570B
			
链接: http://codeforces.com/problemset/problem/570/B http://acm.hust.edu.cn/vjudge/contest/view.action ...
 - Gitlab搭建安装及使用中遇到的问题。
			
一.CentOS7安装gitlab-ce 1.下载及安装rpm软件包. 下载RPM包 curl -LJO https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ ...
 - python实现斐波那契数列笔记
			
斐波那契数列即著名的兔子数列:1.1.2.3.5.8.13.21.34.…… 数列特点:该数列从第三项开始,每个数的值为其前两个数之和,用python实现起来很简单: a=0 b=1 while b ...