数论劲啊

原题:

小C有一个集合S,里面的元素都是小于M的非负整数。他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S。
小C用这个生成器生成了许多这样的数列。但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中所有数的乘积mod M的值等于x的不同的数列的有多少个。小C认为,两个数列{Ai}和{Bi}不同,当且仅当至少存在一个整数i,满足Ai≠Bi。另外,小C认为这个问题的答案可能很大,因此他只需要你帮助他求出答案mod 1004535809的值就可以了。
1<=N<=10^9,3<=M<=8000,M为质数,0<=x<=M-1,输入数据保证集合S中元素不重复

首先因为M是质数并且0<=x和S中的元素<=M-1,就说明M有原根而且能很快求出来

于是对于i∈[0,M-1]的数都可以表示成原根的ki(k∈[0,M-1])次幂形式而且k互补相同

于是乘法就转化成了幂的加法,问题变成给|S|个数,求选n个数使得这n个数的和膜M==x的方案数(一个数可以选多次

所以生成函数,对于每个集合中的数si的ki,用ai表示kj==i有多少个(实际上最多只有一个,因为ki互不相同,同时S中的数互不相同

那么最终生成的多项式就是A=a_0+a_1*x+a_2*x^2+……a_{m-1}*x^{m-1}

因为有n个物品,所以多项式卷积n次

因为给的模数是恩梯梯模数,所以使用NTT计算精确答案

最后的答案就是(A^n)的第k_{x}相

代码:

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
const ll mo=;
int rd(){int z=,mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mk;
}
int wtp=,wtc[];
void wt(int x,char y){
if(!x){ putchar(''); return ;}
if(x<) putchar('-'),x=-x;
while(x) wtc[++wtp]=x%+'',x/=;
while(wtp) putchar(wtc[wtp--]);
putchar(y);
}
ll n,m,t,s; int g,tg[];
ll a[],b[],tmp[],_x,_y;
int rvs[],dg[],N,L; ll _1_N;
int stck[],tp=;
ll qcp(ll x,int y,int p){
ll z=,bs=x;
for(;y;y>>=){
if(y&) z=(z*bs)%p;
bs=(bs*bs)%p;
}
return z;
}
int gtg(){
int _m=m-;
for(int i=;i<=_m;++i)if(!(_m%i)){
stck[++tp]=i;
while(!(_m%i)) _m/=i;
}
for(int i=,mk=false;;++i,mk=false){
for(int j=;j<=tp;++j)
if(qcp(i,(m-)/stck[j],m)==){
mk=true;
break;
}
if(!mk) return i;
}
}
void ntt(ll x[],ll mk){
for(int i=;i<N;++i) tmp[i]=x[rvs[i]];
for(int i=;i<N;++i) x[i]=tmp[i];
for(int i=;i<=N;i<<=){
ll wn=qcp(,(mk*((mo-)/i))%(mo-),mo);
for(int k=;k<N;k+=i){
ll w=;
for(int j=k;j<k+(i>>);++j){
_x=x[j],_y=(x[j+(i>>)]*w)%mo;
x[j]=(_x+_y)%mo,x[j+(i>>)]=(_x-_y+mo)%mo;
w=(w*wn)%mo;
}
}
}
if(mk==mo-) for(int i=;i<N;++i) x[i]=(x[i]*_1_N)%mo;
}
void cclt(){
b[]=;
for(;n;n>>=){
ntt(a,);
if(n&){
ntt(b,); for(int i=;i<N;++i) b[i]=(b[i]*a[i])%mo;
ntt(b,mo-); for(int i=N-;i>=m-;--i) b[i-m+]=(b[i-m+]+b[i])%mo,b[i]=;
}
for(int i=;i<N;++i) a[i]=(a[i]*a[i])%mo;
ntt(a,mo-);
for(int i=N-;i>=m-;--i) a[i-m+]=(a[i-m+]+a[i])%mo,a[i]=;
}
}
int main(){//freopen("ddd.in","r",stdin);
cin>>n>>m>>t>>s;
g=gtg();
for(int i=,x=;i<m-;++i,x=(x*g)%m) tg[x]=i;
int x;
for(int i=;i<=s;++i){
x=rd();
if(x) ++a[tg[x]];
}
for(N=,L=;N<=m;N<<=,++L); N<<=,++L;
_1_N=qcp(N,mo-,mo);
for(int i=;i<N;++i){
for(int j=i,k=;j;j>>=,++k) dg[k]=j&;
for(int j=;j<L;++j) rvs[i]=(rvs[i]<<)|dg[j];
}
cclt();
cout<<b[tg[t]]<<endl;
return ;
}

【BZOJ3992】【SDOI2015】序列统计的更多相关文章

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

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

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

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

  3. BZOJ3992: [SDOI2015]序列统计

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

  4. 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− ...

  5. 【动态规划】bzoj3992 [Sdoi2015]序列统计 10分

    #include<cstdio> using namespace std; #define MOD 1004535809 int a[8001],f[1001][101],n,m,x,S; ...

  6. 【NTT】bzoj3992: [SDOI2015]序列统计

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

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

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

  8. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

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

  9. BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]

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

  10. [SDOI2015]序列统计

    [SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...

随机推荐

  1. web技术栈中不可或缺的Linux技术

    Web技术最重要的载体便是服务器,服务器运行在公共的网络环境下,为广大的用户提供网页浏览.信息通讯.消息推送等服务,从最开始的硬件服务器到虚拟主机技术,再到虚拟化技术的出现和云概念的兴起,绝大部分都是 ...

  2. jquery 操作table样式拖动参考

    参考: http://blog.csdn.net/kdiller/article/details/6059727 http://www.jb51.net/article/59795.htm

  3. 安装babel

    http://jamesknelson.com/using-es6-in-the-browser-with-babel-6-and-webpack/

  4. ASPNET MVC5 根 core

    Asp.Net Core MVC的开源地址:https://github.com/aspnet/Mvc Asp.net MVC的开源地址:http://aspnetwebstack.codeplex. ...

  5. CodeForces - 780C Andryusha and Colored Balloons(dfs染色)

    Andryusha goes through a park each day. The squares and paths between them look boring to Andryusha, ...

  6. Enhancement in SAP abap.

    Recently I have been taught through how to do enhancement for those standard programs. Th reason for ...

  7. python 基础 内置函数 和lambda表达式

    1.把任意数值转化为字符串有两种方法. (1)str()用于将数值转化为易于人读的形式.print(str("我是中国人"))>>>我是中国人 (2)repr() ...

  8. python实现数组和链表的归并排序

    归并排序是一种稳定的排序,采用分而治之策略,可以用于顺序储存结构,也易于在链表上实现.其原理如下图: 算法时间复杂度为  O(nlogn),空间复杂度为 O(n). 1 在数组上实现 def merg ...

  9. python学习笔记第一周

    目录: 一.基础概念 1.变量与常量介绍 2.引号的使用 3.条件判断 4.while与for循环 5.input输入 6.getpass模块 7.python编码 二.作业 1.个人登录系统 2.多 ...

  10. WordPress无插件实现SMTP给评论用户发送邮件提醒

    wordpress中集成PHPMalier给评论用户发送邮件提醒 首先你得去下载PHPMalier.  注:PHPMailer需PHP的socket扩展支持.如果PHPMailer连接邮箱需要ssl加 ...