【题解】SDOI2015序列统计
【题解】SDOI2015序列统计
来自永不AFO的YYB的推荐
这里是乘积,比较麻烦,不过由于给定的序列膜数是个小质数,所以可以\(O(m^2\log m)\)找原跟(实际上不需要这么多)。
乘积有点麻烦,转换成加法就好了,然后取离散对数\(a_i\equiv g^{c_i} \mod m\),现在每个元素都用原根的指数代替了,问题就转变成了有多少种方案使得每个元素的乘积等于\(\log x\mod m\)。
根据题意直接构造
\]
答案就是
\]
吗?
其实要魔改一下,乘的过程中要不断地让\(F(x)\)大于\(x^m\)的系数算到\(x^{i \mod m}\)上,原因显然,略。
不能这么敷衍,到时候自己看会一头雾水,取膜的原因是,我们利用的是多项式乘法的组合意义,现在组合意义是要得到\(c_i=\sum_\limits{k+j \equiv i \mod m}a_kb_j\),所以如此。
既然要不断地让\(F(x)\)对\(x^m\)取膜,所以\(\ln ,\exp\)废了
直接写两个\(\log\)快速幂跑得飞快
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
int n,m,x,s,g;
vector < int > ve;
const int maxn=8009;
int lg[maxn];
int read[1<<19|1];
int ans[1<<19|1];
namespace poly{
const int maxn=1<<19|1;
int a[maxn],b[maxn],r[maxn];
int savlen;
inline void getr(const int&len){
if(len==savlen)return;
int cnt=0;
for(register int t=1;t<len;t<<=1)++cnt;
for(register int t=1;t<len;++t)
r[t]=r[t>>1]>>1|(t&1)<<cnt>>1;
}
const int mod=1004535809;
const int g=3;
inline int ksm(int base,ll p){
register int ret=1;
for(base%=mod;p;p>>=1,base=1ll*base*base%mod)
if(p&1) ret=1ll*ret*base%mod;
return ret;
}
const int gi=ksm(3,mod-2);
inline void NTT(int*a,const int&len,const int&tag){
getr(len);
for(register int t=1;t<len;++t)
if(r[t]>t) swap(a[t],a[r[t]]);
int *a1,*a0,s=g;
if(tag!=1) s=gi;
for(register int t=1,wn;t<len;t<<=1){
wn=ksm(s,(mod-1)/(t<<1));
for(register int i=0;i<len;i+=t<<1){
a1=(a0=a+i)+t;
for(register int j=0,w=1,tm;j<t;++j,++a1,++a0,w=1ll*w*wn%mod){
tm=1ll**a1*w%mod;
*a1=(*a0-tm)%mod;
*a0=(*a0+tm)%mod;
if(*a1<0)*a1+=mod;
}
}
}
if(tag!=1)
for(register int t=0,in=ksm(len,mod-2);t<len;++t)
a[t]=1ll*a[t]*in%mod;
}
inline void print(int*a,int len){
for(register int t=0;t<len;++t)
printf("%d ",a[t]);
putchar('\n');
}
inline void KSM(int*a,int*b,const int&len,int p){
static int ret[maxn],base[maxn];
memset(ret,0,sizeof ret);
memset(base,0,sizeof base);
ret[0]=1;
for(register int t=0;t<len;++t) base[t]=a[t];
while(p){
NTT(base,len<<1,1);
if(p&1){
NTT(ret,len<<1,1);
for(register int t=0;t<len<<1;++t) ret[t]=1ll*ret[t]*base[t]%mod;
NTT(ret,len<<1,-1);
for(register int t=(len<<1)-1;t-m+1>=0;--t) ret[t-m+1]=(ret[t-m+1]+ret[t])%mod,ret[t]=0;
}
for(register int t=0;t<len<<1;++t) base[t]=1ll*base[t]*base[t]%mod;
NTT(base,len<<1,-1);
for(register int t=(len<<1)-1;t-m+1>=0;--t) base[t-m+1]=(base[t-m+1]+base[t])%mod,base[t]=0;
p>>=1;
}
for(int t=0;t<len;++t) b[t]=ret[t];
}
}
inline int ksm(const int&base,const int&p,const int&mod=m){
register int ret=1;
for(register int t=p,b=base%mod;t;t>>=1,b=1ll*b*b%mod)
if(t&1) ret=1ll*ret*b%mod;
return ret;
}
inline void findg(){
#define mod m
int k=m-1;
for(register int t=2;1ll*t*t<=k;++t){
if(k%t==0){
ve.push_back(t);
if(k/t!=t) ve.push_back(k/t);
}
}
//for(auto f:ve) cout<<"fac="<<f<<endl;
for(register int t=2;;++t){
int l=1;
for(auto f:ve)
if(ksm(t,f)==1) l=0;
if(l) {g=t;return;}
}
#undef mod
}
int main(){
freopen("sdoi2015_sequence.in","r",stdin);
freopen("sdoi2015_sequence.out","w",stdout);
n=qr();m=qr();x=qr();s=qr();
findg();
for(register int t=1,k=g;t<m-1;++t,k=1ll*k*g%m) lg[k]=t;
for(register int t=1;t<=s;++t) {int t1=qr();if(t1)read[lg[t1]]=1;}
int k=1;
while(k<=m) k<<=1;
poly::KSM(read,read,k,n);
//for(register int t=0;t<k;++t) cout<<read[t]<<' ';
//cout<<endl;
int ans=read[lg[x]];
printf("%d\n",ans);
return 0;
}
【题解】SDOI2015序列统计的更多相关文章
- [题解] [SDOI2015] 序列统计
题面 题解 设 \(f[i][j]\) 代表长度为 \(i\) 的序列, 乘积模 \(m\) 为 \(j\) 的序列有多少个 转移方程如下 \[ f[i + j][C] = \sum_{A*B\equ ...
- [BZOJ 3992][SDOI2015]序列统计
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 2275 Solved: 1090[Submit][Stat ...
- 【LG3321】[SDOI2015]序列统计
[LG3321][SDOI2015]序列统计 题面 洛谷 题解 前置芝士:原根 我们先看一下对于一个数\(p\),它的原根\(g\)有什么性质(好像就是定义): \(g^0\%p,g^1\%p,g^2 ...
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
- BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)
3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...
- 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 ...
- [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1888 Solved: 898[Submit][Statu ...
随机推荐
- laravel setxxAttribute和getxxAttribute的使用
setxxAttribute 在设置(sql: insert update) 的时候 会将$obj->xx = 'value'的时候, 操作数据库之前 自动转化一下 getxxAttribute ...
- console.log详细介绍
console.log详细介绍 效果图: 代码如下: console.log("%c hello world!:http://www.baidu.com","color: ...
- 高级PHP开发:利用PHPEMS搭建在线考试平台
今天给大家分享一个小技巧,就是利用PHP ems搭建在线考试平台:希望能给你给予帮助: 在给大家分享之前,这里推荐下我自己建的PHP开发-VIP资料出售平台 :638965404,不管你是小白还是大牛 ...
- redis 清除缓存
- JavaWeb项目结构和classpath:
以tomcat为例 项目结构 开发时的项目结构 蓝框 : 存放java文件 绿框 : 存放配置文件 红框 : 存放前台代码 这个项目结构大家都很熟悉,那么当项目被部署到tomcat中时,项目的结构会发 ...
- 2019-8-31-PowerShell-通过-WMI-获取系统信息
title author date CreateTime categories PowerShell 通过 WMI 获取系统信息 lindexi 2019-08-31 16:55:58 +0800 2 ...
- POJ 1961 Period 还是next数组的含义、
题意:求所给串的前缀(包括原串)中有多少循环串(子串长度至少要是周期的两倍) 思路:还是next数组的应用问题.如果不懂next数组的话 http://www.cnblogs.com/sasuke-/ ...
- HDU 1026 BSF+优先队列+记录路径、
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #inclu ...
- BERT的通俗理解 预训练模型 微调
1.预训练模型 BERT是一个预训练的模型,那么什么是预训练呢?举例子进行简单的介绍 假设已有A训练集,先用A对网络进行预训练,在A任务上学会网络参数,然后保存以备后用,当来一个新 ...
- git的安装与命令行基本的使用
1.https://git-scm.com/ 点击这个网址进入git的官方网站 2,.进去里面会有提示,64位于32位的,根据自己的电脑安装 3 下载完了过后就直接安装,一般会安装在c盘里面 ,进入安 ...