https://www.lydsy.com/JudgeOnline/problem.php?id=3992

https://www.luogu.org/problemnew/show/P3321

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

参考:http://www.cnblogs.com/candy99/p/6391483.html

打眼一看模数就是一个原根为3的MTT质数,先敲(抄)为敬。

然后求方案,美滋滋生成函数求完之后n次幂。

emmm然而生成函数只能做加法不能乘啊怎么办?

我们可以把乘法换成加法啊!

曾经做过一道题,把所有数取log……emmm这题显然不行。

(瞄了眼题解……

哇用原根表示数,这样乘法就表示成了指数之间的加法真是非常妙啊!

(当然注意对指数要对m-1取模才行)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const ll P=;
const int G=;
const int N=3e4+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
ll qpow(ll a,ll n,ll p){
ll res=;
while(n){
if(n&)res=res*a%p;
a=a*a%p;n>>=;
}
return res;
}
void MTT(ll a[],int n,int on){
for(int i=,j=n>>;i<n-;i++){
if(i<j)swap(a[i],a[j]);
int k=n>>;
while(j>=k){j-=k;k>>=;}
if(j<k)j+=k;
}
for(int i=;i<=n;i<<=){
ll res=qpow(G,(P-)/i,P);
for(int j=;j<n;j+=i){
ll w=;
for(int k=j;k<j+i/;k++){
ll u=a[k],t=w*a[k+i/]%P;
a[k]=(u+t)%P;
a[k+i/]=(u-t+P)%P;
w=w*res%P;
}
}
}
if(on==-){
ll inv=qpow(n,P-,P);
a[]=a[]*inv%P;
for(int i=;i<=n/;i++){
a[i]=a[i]*inv%P;
if(i!=n-i)a[n-i]=a[n-i]*inv%P;
swap(a[i],a[n-i]);
}
}
}
vector<int>v;
bool pan(int g,int p){
for(int i=;i<v.size();i++){
if(qpow(g,(p-)/v[i],p)==)return ;
}
return ;
}
int primitive(int p){
int res=p-;v.clear();
for(int i=;i*i<=res;i++){
if(res%i==){
v.push_back(i);
while(res%i==)res/=i;
}
}
if(res!=)v.push_back(res);
for(int i=;;i++){
if(pan(i,p))return i;
}
}
int nn,n,m,x,s,sum,ind[N];
void multi(ll a[],ll b[]){
static ll c[N];
for(int i=;i<nn;i++)c[i]=b[i];
MTT(a,nn,);MTT(c,nn,);
for(int i=;i<nn;i++)a[i]=a[i]*c[i]%P;
MTT(a,nn,-);
for(int i=;i<m-;i++)
a[i]=(a[i]+a[i+m-])%P,a[i+m-]=;
}
void sqr(ll a[]){
MTT(a,nn,);
for(int i=;i<nn;i++)a[i]=a[i]*a[i]%P;
MTT(a,nn,-);
for(int i=;i<m-;i++)
a[i]=(a[i]+a[i+m-])%P,a[i+m-]=;
}
ll a[N],ans[N];
int main(){
n=read(),m=read(),x=read(),s=read();
int g=primitive(m),k=;
for(int i=;i<m-;i++){
ind[k]=i;k=k*g%m;
}
for(int i=;i<=s;i++){
int w=read();
if(w)a[ind[w]]=;
}
nn=;ans[]=;
while(nn<*m)nn<<=;
while(n){
if(n&)multi(ans,a);
sqr(a);n>>=;
}
printf("%lld\n",ans[ind[x]]);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

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]序列统计 【生成函数 + 多项式快速幂】

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

  4. BZOJ3992: [SDOI2015]序列统计

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

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

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

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

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

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

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

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

  9. 【题解】SDOI2015序列统计

    [题解]SDOI2015序列统计 来自永不AFO的YYB的推荐 这里是乘积,比较麻烦,不过由于给定的序列膜数是个小质数,所以可以\(O(m^2\log m)\)找原跟(实际上不需要这么多). 乘积有点 ...

随机推荐

  1. VIM第七版

    ZZ:退出并保存 e!:退回到上次保存时的样子 cw:修改单词(自动进入插入模式) cc:修改一整行的内容 cs:修改一个词(自动进入插入模式) .:可以重复上一个命令 J:将下一行内容合并到本行末尾 ...

  2. python基础之全局局部变量及函数参数

    1.局部变量和全局变量 1.1局部变量 局部变量是在函数内部定义的变量,只能在定义函数的内部使用 函数执行结束后,函数内部的局部变量会被系统收回 不同函数可以定义相同名字的局部变量,但是各用个的互不影 ...

  3. lintcode 平面列表

    问题描述: 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 样例: 给定 [1,2,[1,2]],返回 [1,2,1,2]. 给定 [4,[3,[2,[1 ...

  4. Android开发-API指南-<supports-screens>

    <supports-screens> 英文原文:http://developer.android.com/guide/topics/manifest/supports-screens-el ...

  5. C++ ifndef /define/ endif 作用和用法

    ifndef/define/endif”主要目的是防止头文件的重复包含和编译 比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题 ...

  6. Java开发中用的比较多的数据结构

    java 中几种常用数据结构 2016年07月11日 09:11:27 阅读数:83211 标签: 数据结构java 更多 个人分类: 自行学习   JAVA中常用的数据结构(java.util. 中 ...

  7. WCF:REST + Basic authentification + IIS

    近期一个项目中用到Restful WCF提供服务,但是需要验证机制,网上搜刮了一些,都是太复杂.FQ找到了一篇不错的文章分享一下. 原地址连接:http://vgolovchenko.wordpres ...

  8. mysql 启动报错

    之前用我这个机器做mysql的测试来,今天启动准备搭建一套线上的主从,结果起不来了... 错误日志: ;InnoDB: End of page dump 170807 11:37:02 InnoDB: ...

  9. Alpha 冲刺(2/10)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 协助前端界面的开发 搭建测试用服务器的环境 完成 ...

  10. NSTimer使用注意事项

    1.scheduled开头和非schedule的开头方法的区别.系统框架提供了几种创建NSTimer的方法,其中以scheduled开头的方法会自动把timer加入当前run loop,到了设定的时间 ...