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. 转:asp.net mvc ef 性能监控调试工具 MiniProfiler

    MiniProfiler官网:http://miniprofiler.com/ MiniProfiler的一个特别有用的功能是它与数据库框架的集成.除了.NET原生的 DbConnection类,Mi ...

  2. hadoop 家族图

    hadoop家族

  3. 【廖雪峰老师python教程】——进程与线程

    多进程 操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去.表面上看,每个任务都是交替执行的,但是,由于CPU ...

  4. Python3开启Http服务

    在CMD命令行输入D: 切换到D盘, 然后输入 python -m http.server 8000 开启HTTP服务: 在浏览器地址栏输入 http://localhost:8000/

  5. web自动化原理揭秘

    做过两年自动化测试的小伙伴说web自动化测试真的不难,无非就是一些浏览器操作,页面元素操作,常规的情况很容易处理,再学一学特殊元素的处理,基本就能应付项目的测试了. 这个话倒没错,但是真正要学好自动化 ...

  6. 游戏AI之群组行为

    群组行为指的是多个对象组队同时进行的情况.每个boid需满足分离,队列,凝聚三个基本的规则. 分离:群组中的每个个体都与相邻的个体保持一定的距离. 队列:群组以相同的速度,向相同的方向移动. 凝聚:与 ...

  7. 在deepin系统中制作桌面快捷方式

    在使用deepin-wine 安装一些软件的时候,每次启动都需要到.deepinwine目录下运行deepin-wine xx.exe.笔者在安装过HeidiSql之后,一直苦于这种情况.比较好的解决 ...

  8. C struct中的位域 bitfield

    C struct中的位域 bitfield 结构体的成员可以限制其位域,每个成员可以使用用比字节还小的取值范围,下面的结构体s1中,四个成员每个成员都是2bit的值(0~3),整个结构体占据的空间依然 ...

  9. Python3 Tkinter-PaneWindow

    1.向PanedWindow中添加Pane from tkinter import * root=Tk() panes=PanedWindow(orient=VERTICAL) panes.pack( ...

  10. Thunder团队第一周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:在线考试系统 Scrum Master:杨梓瑞 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李 ...