传送门

生成函数简单题。

题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1​,a2​,...as​},所有数都在[0,m−1][0,m-1][0,m−1]之间,mmm是一个质数,求满足全部由这个集合里的组成且长度为nnn且所有数之积与xxx在模mmm意义下相同的数列总数。


思路:对a1,a2,..,as,xa_1,a_2,..,a_s,xa1​,a2​,..,as​,x全部化成gb1,gb2,...gbs,gyg^{b_1},g^{b_2},...g^{b_s},g^{y}gb1​,gb2​,...gbs​,gy,然后就转乘法为加法。

于是只用求x1+x2+...+xn≡ymod  m−1x_1+x_2+...+x_n\equiv y\mod m-1x1​+x2​+...+xn​≡ymodm−1,其中xi∈{b1,b2,...bs}x_i\in\{b_1,b_2,...b_s\}xi​∈{b1​,b2​,...bs​}的方案数。

对于xix_ixi​可以构造出生成函数1+xb1+xb2+...+xbs1+x^{b_1}+x^{b_2}+...+x^{b_s}1+xb1​+xb2​+...+xbs​,于是答案的生成函数就是(1+xb1+xb2+...+xbs)n(1+x^{b_1}+x^{b_2}+...+x^{b_s})^n(1+xb1​+xb2​+...+xbs​)n,考虑到nnn很大可以用快速幂+nttnttntt解决。

注意特判ai=0a_i=0ai​=0的情况以及每次nttnttntt完了之后要重新把多项式的最高次数控制为m−2m-2m−2

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=3e6+5,mod=1004535809;
int M,lim=1,tim=0,pos[N],a[N],P,n,x,idx[N];
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;}
inline void ntt(int a[],int type){
	for(ri i=0;i<lim;++i)if(i<pos[i])swap(a[i],a[pos[i]]);
	for(ri wn,mult=(mod-1)>>1,typ=type==1?3:334845270,mid=1;mid<lim;mid<<=1,mult>>=1){
		wn=ksm(typ,mult);
		for(ri j=0,len=mid<<1;j<lim;j+=len)for(ri w=1,k=0,a0,a1;k<mid;++k,w=mul(w,wn)){
			a0=a[j+k],a1=mul(w,a[j+k+mid]);
			a[j+k]=add(a0,a1),a[j+k+mid]=dec(a0,a1);
		}
	}
	if(type==-1)for(ri inv=ksm(lim,mod-2),i=0;i<lim;++i)a[i]=mul(a[i],inv);
}
inline void poly_mul(int a[],int b[]){
	static int A[N],B[N];
	for(ri i=0;i<lim;++i)A[i]=a[i],B[i]=b[i];
	ntt(A,1),ntt(B,1);
	for(ri i=0;i<lim;++i)A[i]=mul(A[i],B[i]);
	ntt(A,-1);
	for(ri i=0;i<lim;++i)a[i]=A[i];
	for(ri i=lim-1;i>=M-1;--i)a[i-M+1]=add(a[i-M+1],a[i]),a[i]=0;
}
inline void solve(int a[],int p){
	static int ret[N];
	memset(ret,0,sizeof(ret)),ret[0]=1;
	for(;p;p>>=1,poly_mul(a,a))if(p&1)poly_mul(ret,a);
	cout<<ret[x];
}
inline bool check(int g){
	for(ri i=0;i<M;++i)idx[i]=-1;
	for(ri i=0,mul=1;i<M-1;++i,mul=mul*g%M){
		if(~idx[mul])return 0;
		idx[mul]=i;
	}
	return 1;
}
inline void init(){
	while(lim<=M*2)lim<<=1,++tim;
	for(ri i=0;i<lim;++i)pos[i]=(pos[i>>1]>>1)|((i&1)<<(tim-1));
	for(ri g=1;!check(g);++g);
}
int main(){
    P=read(),M=read(),init(),x=idx[read()],n=read();
    while(n--){
    	int x=read();
    	if(!x)continue;
    	a[idx[x]]=1;
	}
    solve(a,P);
    return 0;
}

2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)的更多相关文章

  1. LOJ 2183 / SDOI2015 序列统计 (DP+矩阵快速幂)

    题面 传送门 分析 考虑容斥原理,用总的方案数-不含质数的方案数 设\(dp1[i][j]\)表示前i个数,和取模p为j的方案数, \(dp2[i][j]\)表示前i个数,和取模p为j的方案数,且所有 ...

  2. [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)

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

  3. 【bzoj3992】[SDOI2015]序列统计 原根+NTT

    题目描述 求长度为 $n$ 的序列,每个数都是 $|S|$ 中的某一个,所有数的乘积模 $m$ 等于 $x$ 的序列数目模1004535809的值. 输入 一行,四个整数,N.M.x.|S|,其中|S ...

  4. BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)

    题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...

  5. BZOJ3992: [SDOI2015]序列统计

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

  6. bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】

    还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...

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

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

  8. 2018.12.31 bzoj4001: [TJOI2015]概率论(生成函数)

    传送门 生成函数好题. 题意简述:求nnn个点的树的叶子数期望值. 思路: 考虑fnf_nfn​表示nnn个节点的树的数量. 所以有递推式f0=1,fn=∑i=0n−1fifn−1−i(n>0) ...

  9. 【BZOJ3992】【SDOI2015】序列统计 EGF+多项式快速幂+循环卷积

    如果是求$n$个数之和在模$m$意义下为$x$,那么做法是显然的. 但是这道题问的是$n$个数之积在模m意义下为$x$,那么做法就和上面的问题不同. 考虑如何把乘法转换成加法(求log): 题目中有一 ...

随机推荐

  1. Watcher、ZK状态、事件类型 ,权限

    zookeeper有watch事件,是一次性触发的,当watch监视的数据发生变化时,通知设置了该watch的client,即watcher. 同样,其watcher是监听数据发送了某些变化,那就一定 ...

  2. jquery is()和has()方法

    1. is() :判断当前节点是否是否匹配选择器.返回布尔值: 2. has():判断当前节点是否包含选择器中的子元素,返回包含固定子元素的父元素(jquery对象) 用法:可用于判断父元素中是否包含 ...

  3. pycurl提示load dll failed 找不到注册程序

    原因:python虽然是2.7的 但有小版本区别 建议使用2.7.8

  4. AttributeError: 'WebElement' object has no attribute 'send_keys'

    这个是没问题的代码:用来打开谷歌搜索cheese并退出 from selenium import webdriver from selenium.common.exceptions import Ti ...

  5. Split Array into Consecutive Subsequences

    659. Split Array into Consecutive Subsequences You are given an integer array sorted in ascending or ...

  6. JS如何获取上传标签的文件路径和文件名?

    如何使用JS获取type="file"的标签上传文件的文件路径及文件名: 代码: <!doctype html><html lang="en" ...

  7. python 面向对象编程 之 析构方法

    析构方法:当对象在内存中被释放的时候,自动触发执行 如果产生的对象仅仅只是用户级别的, 那么无需定义__del__,如果对象还会向操作系统发生系统调用, 即一个对象有用户级别与内核级两种资源, 比如打 ...

  8. C# fckeditor添加上传附件功能

    最近在维护系统时,要把fckediotr加上上传附件功能,好久没有用fckeditor了,现在都已经改名字,不叫这个了. 修改统计器下面的fckconfig.js,方法如下: 1.把FCKConfig ...

  9. Spring Boot 2.0(三):使用 Docker 部署 Spring Boot

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  10. apt install yum失败

    解决办法:sudo apt-get update