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−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+快速幂)的更多相关文章
- 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]序列统计 原根+NTT
题目描述 求长度为 $n$ 的序列,每个数都是 $|S|$ 中的某一个,所有数的乘积模 $m$ 等于 $x$ 的序列数目模1004535809的值. 输入 一行,四个整数,N.M.x.|S|,其中|S ...
- BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)
题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...
- BZOJ3992: [SDOI2015]序列统计
Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列. ...
- bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根--题目提示其实挺明显的,M是质数,然后1<=x<=M-1 这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法 首先因为0和任何数乘都是0 ...
- BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】
题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...
- 2018.12.31 bzoj4001: [TJOI2015]概率论(生成函数)
传送门 生成函数好题. 题意简述:求nnn个点的树的叶子数期望值. 思路: 考虑fnf_nfn表示nnn个节点的树的数量. 所以有递推式f0=1,fn=∑i=0n−1fifn−1−i(n>0) ...
- 【BZOJ3992】【SDOI2015】序列统计 EGF+多项式快速幂+循环卷积
如果是求$n$个数之和在模$m$意义下为$x$,那么做法是显然的. 但是这道题问的是$n$个数之积在模m意义下为$x$,那么做法就和上面的问题不同. 考虑如何把乘法转换成加法(求log): 题目中有一 ...
随机推荐
- Watcher、ZK状态、事件类型 ,权限
zookeeper有watch事件,是一次性触发的,当watch监视的数据发生变化时,通知设置了该watch的client,即watcher. 同样,其watcher是监听数据发送了某些变化,那就一定 ...
- jquery is()和has()方法
1. is() :判断当前节点是否是否匹配选择器.返回布尔值: 2. has():判断当前节点是否包含选择器中的子元素,返回包含固定子元素的父元素(jquery对象) 用法:可用于判断父元素中是否包含 ...
- pycurl提示load dll failed 找不到注册程序
原因:python虽然是2.7的 但有小版本区别 建议使用2.7.8
- AttributeError: 'WebElement' object has no attribute 'send_keys'
这个是没问题的代码:用来打开谷歌搜索cheese并退出 from selenium import webdriver from selenium.common.exceptions import Ti ...
- Split Array into Consecutive Subsequences
659. Split Array into Consecutive Subsequences You are given an integer array sorted in ascending or ...
- JS如何获取上传标签的文件路径和文件名?
如何使用JS获取type="file"的标签上传文件的文件路径及文件名: 代码: <!doctype html><html lang="en" ...
- python 面向对象编程 之 析构方法
析构方法:当对象在内存中被释放的时候,自动触发执行 如果产生的对象仅仅只是用户级别的, 那么无需定义__del__,如果对象还会向操作系统发生系统调用, 即一个对象有用户级别与内核级两种资源, 比如打 ...
- C# fckeditor添加上传附件功能
最近在维护系统时,要把fckediotr加上上传附件功能,好久没有用fckeditor了,现在都已经改名字,不叫这个了. 修改统计器下面的fckconfig.js,方法如下: 1.把FCKConfig ...
- Spring Boot 2.0(三):使用 Docker 部署 Spring Boot
Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...
- apt install yum失败
解决办法:sudo apt-get update