Luogu P3321 [SDOI2015]序列统计
一道不错的多项式好题。还涉及了一些数论内容。
首先我们看到题目是求乘积模\(m\)的方案数,考虑到这种方案数我们一般都可以用生成函数来做。
但显然卷积的下标有加(FFT,NTT等)有位运算(FWT)但是没有乘法的。除非您十分dalao自己发明一个卷积算法
所以我们考虑化乘为加,我们注意到\(m\)是一个不大的指数,那么意味这我们可以利用同余系下的一大利器——原根
关于原根的主要性质,其实就是原根\(g\),满足\(g^0,g^1\dots g^{m-2}\)模\(m\)后各不相同。
所以我们可以暴力找出原根(可以参考dalao's blog),然后把每一个数转化为原根的幂指数
这样我们把两个数相乘时其实就是指数相加,那么直接多项式快速幂即可。
但是注意到这里的下标其实是在模意义下的,并且根据欧拉定理我们还可以知道指数模的是\(m-1\)(不是\(m\)!),这个我们在做完NTT时把跑到后面的项手动加到前面去就可以了。
复杂度\(O(m\log^2 n)\),实测跑得非常快。
CODE
#include<cstdio>
#define RI register int
using namespace std;
const int M=8005,mod=1004535809;
int n,m,tar,s,t,x,root,A[M<<2],rg[M],rst[M],cnt;
inline int quick_pow(int x,int r,int p=mod,int mul=1)
{
for (;r;r>>=1,x=1LL*x*x%p) if (r&1) mul=1LL*mul*x%p; return mul;
}
inline int get_root(int x)
{
RI i; for (i=2;i<=x-2;++i) if ((x-1)%i==0)
rg[++cnt]=i; for (i=2;;++i)
{
bool flag=1; for (RI j=1;j<=cnt;++j)
if (quick_pow(i,rg[j],x)==1) { flag=0; break; }
if (flag) return i;
}
}
inline void inc(int& x,int y)
{
if ((x+=y)>=mod) x-=mod;
}
inline void dec(int& x,int y)
{
if ((x-=y)<0) x+=mod;
}
class Poly_Solver
{
private:
int rev[M<<2],T[M<<2],lim,p;
inline void init(int n)
{
for (lim=1;lim<=n;lim<<=1,++p);
for (RI i=0;i<lim;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<p-1);
}
inline void swap(int& x,int& y)
{
int t=x; x=y; y=t;
}
inline void NTT(int *f,int opt)
{
RI i; for (i=0;i<lim;++i) if (i<rev[i]) swap(f[i],f[rev[i]]);
for (i=1;i<lim;i<<=1)
{
int m=i<<1,D=quick_pow(3,opt==1?(mod-1)/m:mod-1-(mod-1)/m);
for (RI j=0;j<lim;j+=m)
{
int W=1; for (RI k=0;k<i;++k,W=1LL*W*D%mod)
{
int x=f[j+k],y=1LL*f[i+j+k]*W%mod;
f[j+k]=f[i+j+k]=x; inc(f[j+k],y); dec(f[i+j+k],y);
}
}
}
if (opt==-1)
{
int Inv=quick_pow(lim,mod-2);
for (i=0;i<lim;++i) f[i]=1LL*f[i]*Inv%mod;
}
}
inline void mul_self(int *A)
{
RI i; for (NTT(A,1),i=0;i<lim;++i)
A[i]=1LL*A[i]*A[i]%mod;
NTT(A,-1); for (i=lim-1;i>=m-1;--i) inc(A[i-m+1],A[i]),A[i]=0;
}
inline void mul(int *A,int *B)
{
RI i; for (NTT(A,1),NTT(B,1),i=0;i<lim;++i) A[i]=1LL*A[i]*B[i]%mod;
NTT(A,-1); NTT(B,-1); for (i=lim-1;i>=m-1;--i) inc(A[i-m+1],A[i]),A[i]=0;
}
public:
inline int pow(int *A,int r,int tar)
{
for (init(m<<1),T[0]=1;r;r>>=1,mul_self(A))
if (r&1) mul(T,A); return T[tar];
}
}P;
int main()
{
RI i; scanf("%d%d%d%d",&n,&m,&tar,&s); root=get_root(m);
for (x=i=1;i<=m-2;++i) rst[x=1LL*x*root%m]=i;
for (i=1;i<=s;++i) scanf("%d",&x),x&&(A[rst[x]]=1);
return printf("%d\n",P.pow(A,n,rst[tar])),0;
}
Luogu P3321 [SDOI2015]序列统计的更多相关文章
- Luogu 3321 [SDOI2015]序列统计
BZOJ 3992 点开这道题之后才发现我对原根的理解大概只停留在$998244353$的原根是$3$…… 关于原根: 点我 首先写出$dp$方程,设$f_{i, j}$表示序列长度为$i$当前所有数 ...
- P3321 [SDOI2015]序列统计 FFT+快速幂+原根
\(\color{#0066ff}{ 题目描述 }\) 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这 ...
- [洛谷P3321][SDOI2015]序列统计
题目大意:给你一个集合$n,m,x,S(S_i\in(0,m],m\leqslant 8000,m\in \rm{prime},n\leqslant10^9)$,求一个长度为$n$的序列$Q$,满足$ ...
- P3321 [SDOI2015]序列统计
思路 首先有个挺显然的DP \[ dp[i][(j*k)\%m]+=dp[i-1][j]\times dp[i-1][k] \] 想办法优化这个DP 这个dp也可以写成这样 \[ dp[i][j]=\ ...
- 洛咕 P3321 [SDOI2015]序列统计
显然dp就是设\(f[i][j]\)表示dp了i轮,对m取膜是j的方案数 \(f[i][xy\mod m]=f[i-1][x]\times f[i-1][y]\) 这是\(O(nm^2)\)的 像我这 ...
- 洛谷P3321 [SDOI2015]序列统计(NTT)
传送门 题意:$a_i\in S$,求$\prod_{i=1}^na_i\equiv x\pmod{m}$的方案数 这题目太珂怕了……数学渣渣有点害怕……kelin大佬TQL 设$f[i][j]$表示 ...
- BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1017 Solved: 466[Submit][Statu ...
- [SDOI2015]序列统计
[SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...
- 3992: [SDOI2015]序列统计
3992: [SDOI2015]序列统计 链接 分析: 给定一个集和s,求多少个长度为n的序列,满足序列中每个数都属于s,并且所有数的乘积模m等于x. 设$f=\sum\limits_{i=0}^{n ...
随机推荐
- 自定义控件:Flag标签
效果图: 只有一个自定义textview.源码很简单,可以阅读下. GitHub
- Xamarin.Forms 使用本地数据库之 SQLite
前言 Xamarin.Forms支持使用SQLite数据库引擎.本文介绍了Xamarin.Forms应用程序如何读取和写入数据到使用SQLite.Net的本地SQLite数据库. 在Xamarin.F ...
- ASP.NET Core 入门教程 1、使用ASP.NET Core 构建第一个Web应用
一.前言 1.本文主要内容 Visual Studio Code 开发环境配置 使用 ASP.NET Core 构建Web应用 ASP.NET Core Web 应用启动类说明 ASP.NET Cor ...
- 当年写的如何成为一名MSSQL DBA
很多开发人员都想成为一名数据库培训,也有很多人一开始就把自己定位成为一名DBA,DBA究竟需要掌握些什么知识和技能呢?以下是我 做DBA工作和面试DBA时,整理的一些DBA方面的三十个问 ...
- Python爬虫-05:Ajax加载的动态页面内容
1. 获取AJAX加载动态页面的内容 1.1. Introduction 如果所爬取的网址是通过Ajax方式加载的,就直接抓包,拿他后面传输数据的文件 有些网页内容使用AJAX加载,只要记得,AJAX ...
- [WeChall] Training: Crypto - Caesar I (Crypto, Training)
Training: Crypto - Caesar I (Crypto, Training) Crypto - Caesar I As on most challenge sites, there a ...
- 网络协议与OSI体系结构
网络协议与网络体系结构 一.网络协议的概念 1.含义: 网络协议是计算机间进行通信时遵循的一些约定和规则 2.三要素: (1)语法:用于确定协议元素的格式,即数据与控制信息的结构 (2)语义:用于确定 ...
- Python开发【第二篇】:基本数据类型
运算符 1.算数运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 基本数据类型 所有对象所具备的方法都保存在类中.对象和类的关系,举个例子:哺乳动物是类:此类下有两个对象,一个为狗.一个为 ...
- Linux:自动删除n天前日志
linux是一个很能自动产生文件的系统,日志.邮件.备份等.虽然现在硬盘廉价,我们可以有很多硬盘空间供这些文件浪费,让系统定时清理一些不需要的文件很有一种爽快的事情.不用你去每天惦记着是否需要清理日志 ...
- 从此使用linux系统,但是QQ是必不可少的!!该篇文章方法成功!!!已验证!!!!!
一开始,我在Ubuntu14.04下安装的QQ版本是WineQQ2013SP6-20140102-Longene, 但后来发现这个版本QQ在linux下问题很多,比如不能用键盘输入密码,QQ表情使用失 ...