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): 题目中有一 ...
随机推荐
- Python+Selenium学习--上传文件
场景 文件上传操作也比较常见功能之一,上传功能操作webdriver 并没有提供对应的方法,关键上传文件的思路.上传过程一般要打开一个系统的window 窗口,从窗口选择本地文件添加.所以,一般会卡在 ...
- zkClient的使用
ZKClient是由DataMeer的工程师StefanGroschupf和Peter Voss 一起开发的,在源生API接口基础上进行了封装,简化了ZK的复杂性. 1. 创建客户端方法:ZKClie ...
- spring cloud ribbon和feign的区别
spring cloud的Netflix中提供了两个组件实现软负载均衡调用:ribbon和feign. Ribbon 是一个基于 HTTP 和 TCP 客户端的负载均衡器 它可以在客户端配置 ribb ...
- cocoapods 更新本地仓库 pod setup/update 无限远程中断
升级 cocoapods 无限远程中断:网络不好 试了很多解决方法: 1.替换源,2.设置下载速度,3.清空本地master仓库,4.删了本地的pod库,5.半夜3-5点更新,6.按照失败提示的 (p ...
- REUSE_ALV_FIELDCATALOG_MERGE
作用: 根据程序中的数据内表结构,来自动生成FIELDCAT[]内表,不用定义宏或者Form来一个个加入,会根据内表结构所参照的词典类型来自动完成如表标题字段名的生成,得到大概的FIELDCAT[]后 ...
- String.format的用法
有些时候,对于一些东西,不是没有简单的方法,而是我们没有接触到过 String.format();即创建格式化的字符串,里面有很多的通配使用符号,我这里说一下我接触到的,以后接触到其他的再填坑 它的内 ...
- Wechat微信公众平台开发
一.微信概述 1.历史背景 1)2011年1月21日,腾讯推出微信应用程序.(张小龙) 2)2012年8月20日,腾讯推出微信公众平台功能,同年11月开放第三方接口 3)2013年11月注册用户量突破 ...
- ubuntu14.04 源码安装MySQL
转发麻烦备注本站地址:http://www.cnblogs.com/cyq632694540/p/7053179.html 1.下载源码包 >wget http://dev.mysql.com/ ...
- dev-server.js浅析
// 检查NodeJS和npm的版本 require('./check-versions')() // 获取配置 var config = require('../config') // 如果Node ...
- (四)创建ROS程序包(就是软件包)
你的 ROS 程序包都放到下面这个目录里, 切换到这个目录: $ cd ~/catkin_ws/src 使用下面的命令: 创建一个 ROS 程序包 名字就叫:beginner_tutorials $ ...