题目链接

戳我

题意简述

你有长为\(n\)的序列和\(Q\)个询问,每次询问一个\(k\),求用\(k\)个数组成的不同方案的乘积的和。

sol

显然要预处理一波。

考虑分治,左右两边都求出来后,怎么合并。

设\(A[i]\)为整体用\(i\)个数的乘积和,\(B[i]\)为左边用\(i\)个数的乘积和,\(C[i]\)为右边用\(i\)个数的乘积和。

则很显然有\(A[i]=\sum_{j=0}^i B[j]C[i-j]\)

这是一个卷积然后NTT就好了,然而怎么模数是1e5+3,那就双模数NTT吧,虽然常数巨大,FFT也可以,写的好的话常数优秀5~6倍。总复杂度\(O(nlog^2n)\)。

疯狂压行ing~

#include<cstdio>
#include<cstring>
#include<algorithm>
#define gt getchar()
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
inline int in(){int k=0;char ch=gt;while(ch<'-')ch=gt;while(ch>'-')k=k*10+ch-'0',ch=gt;return k;}
const int N=3e5+5,g=3,p[]={998244353,1004535809},inv[]={669690699,332747959};const ll MOD=1ll*p[0]*p[1];
int rev[N],v1[N],v2[N],v3[N],v4[N];ll f[50][N];
inline int MO(const int &a,int now){return a>=p[now]?a-p[now]:a;}
inline int ksm(int a,int k,int now){int r=1;while(k){if(k&1)r=1ll*r*a%p[now];a=1ll*a*a%p[now],k>>=1;}return r;}
inline ll mul(ll a,ll k ){ll r=0;while(k){if(k&1)r=(r + a)% MOD ;a=(a + a)% MOD ,k>>=1;}return r;}
void get_rev(int len,int qwq){rev[0]=0;for(int i=1;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<qwq-1);}
void ntt(int *a,int len,int opt,int now)
{
#define YL p[now]
for(int i=0;i<len;++i)if(i<rev[i])std::swap(a[i],a[rev[i]]);
for(int st=2,m=1;st<=len;st<<=1,m<<=1)
{
int wn=ksm(g,opt==1?(YL-1)/st:YL-1-(YL-1)/st,now);
for(int *pp=a;pp!=a+len;pp+=st)
for(int k=0,wnk=1;k<m;++k,wnk=1ll*wnk*wn%YL)
{
int t=1ll*wnk*pp[k+m]%YL;
pp[k+m]=MO(pp[k]-t+YL,now);
pp[k]=MO(pp[k]+t,now);
}
}
if(opt==1)return;int inv=ksm(len,YL-2,now);
for(int i=0;i<len;++i)a[i]=1ll*a[i]*inv%YL;
#undef YL
}
const int YL=1e5+3;
int a[N];
void get_mul(int *a,int *b,int len,int now)
{
ntt(a,len, 1,now);ntt(b,len, 1,now);
for(int i=0;i<len;++i)a[i]=1ll*a[i]*b[i]%p[now];
ntt(a,len,-1,now);
}
void cdq_fft(int l,int r,int x)
{
for(int i=0;i<=r-l+1;++i)f[x][i]=0;
if(l==r){f[x][0]=1,f[x][1]=a[l];return;}
int mid=l+r>>1;cdq_fft(l,mid,x+1);
for(int i=0;i<=r-l+1;++i)f[x][i]=f[x+1][i];cdq_fft(mid+1,r,x+1);
int m=r-l+1,qwq=0,len=1;
while(len<=m)len<<=1,++qwq;get_rev(len,qwq);
for(int i=r-mid+1;i<len;++i)f[x+1][i]=0;
for(int i=mid-l+2;i<len;++i)f[ x ][i]=0;
for(int i=0;i<len;++i)v1[i]=v2[i]=f[x][i],v3[i]=v4[i]=f[x+1][i];
get_mul(v1,v3,len,0);get_mul(v2,v4,len,1);
for(int i=0;i<=m;++i)
{
f[x][i]=mul(1ll*v1[i]*p[1]%MOD,inv[1]);
ll tttt=mul(1ll*v2[i]*p[0]%MOD,inv[0]);
f[x][i]=(f[x][i]+tttt)%MOD;
f[x][i]=(f[x][i]+YL)%YL;
}
}
int main()
{
int n=in(),q=in();for(int i=1;i<=n;++i)a[i]=in()%YL;
cdq_fft(1,n,0);while(q--)printf("%lld\n",f[0][in()]);
return 0;
}

51nod乘积之和的更多相关文章

  1. 51nod 1348 乘积之和

    用(r-l+2)维向量f[l,r]表示区间[l,r]内选i个数(0<=i<=r-l+1)相乘的所有方案之和,可以发现f[l,r]=f[l,m]*f[m+1,r],题目模数100003较小, ...

  2. 51Nod 最小公倍数之和V3

    这题公式真tm难推……为了这题费了我一个草稿本…… woc……在51Nod上码LaTeX码了两个多小时…… 一开始码完了前半段,刚码完后半段突然被51Nod吃了,重新码完后半段之后前半段又被吃了,吓得 ...

  3. 51Nod 约数之和

                              1220 约数之和                                  题目来源: Project Euler 基准时间限制:3 秒 ...

  4. POJ1651 Multiplication Puzzle(相邻乘积之和最小,区间DP)

    http://blog.csdn.net/libin56842/article/details/9747021 http://www.cnblogs.com/devil-91/archive/2012 ...

  5. 51 NOD 1238 最小公倍数之和 V3

    原题链接 最近被51NOD的数论题各种刷……(NOI快到了我在干什么啊! 然后发现这题在网上找不到题解……那么既然A了就来骗一波访问量吧…… (然而并不怎么会用什么公式编辑器,写得丑也凑合着看吧…… ...

  6. 51Nod 快速傅里叶变换题集选刷

    打开51Nod全部问题页面,在右边题目分类中找到快速傅里叶变换,然后按分值排序,就是本文的题目顺序. 1.大数乘法问题 这个……板子就算了吧. 2.美妙的序列问题 长度为n的排列,且满足从中间任意位置 ...

  7. 《剑指offer》面试题66. 构建乘积数组

    问题描述 给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×-×A[i-1]×A[i+1]×-×A[n-1].不能使用 ...

  8. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  9. 快速数论变换NTT模板

    51nod 1348 乘积之和 #include <cmath> #include <iostream> #include <cstdio> #include &l ...

随机推荐

  1. 关于springcloud的一些问题总结.txt

    @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCo ...

  2. 来源自rnnoise,但非rnn

    很快又一年过去了. 自学音频算法也近一年了. 不记得有多少个日日夜夜, 半夜醒来,就为验证算法思路. 一次又一次地改进和突破. 傻逼样的坚持,必然得到牛逼样的结果. 这一年,主要扎音频算法上. 经常有 ...

  3. 前端常见算法面试题之 - 从尾到头打印链表[JavaScript解法]

    题目描述 输入一个链表的头结点,从尾到头反过来打印出每个结点的值 实现思路 前端工程师看到这个题目,直接想到的就是,写个while循环来遍历链表,在循环中把节点的值存储在数组中,最后在把数组倒序后,遍 ...

  4. ats 转发代理

    ats是一个通用代理,可配置为反向和转发代理; 转发代理可以用作基础架构中的中央工具来访问web, 它可以与缓存结合使用以降低 总体带宽使用率.转发代理充当本地网络上的客户端浏览器与这些客户端访问的所 ...

  5. MyBatis学习(一)————纯jdbc编程

    什么是JDBC  JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java ...

  6. 遇到执行SQL 的参数最大个数

    报错: 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.此 RPC 请求中提供了过多的参数.最多应为 2100. 现象是: SQL 执行的参数过多,超过了 最大值 :2100 个. ...

  7. Currency Exchange 货币兑换 Bellman-Ford SPFA 判正权回路

    Description Several currency exchange points are working in our city. Let us suppose that each point ...

  8. 互评Alpha版本—SkyHunter

    1.根据NABCD评论作品:   N(Need,需求):飞机大战题材的游戏对80,90后的人来说算是童年的记忆,可以在闲暇之余打开电脑玩一会儿.但是面向初中生,高中生的话这种PC小游戏可能不会那么适合 ...

  9. Git的基本使用方法和安装&心得体会(使用git命令行)

    这是补发的,使用命令行操作的. (1)选择本地repository的路径 找到后点鼠标右键,选择git bash here. (2) clone到本地 在命令行输入 git clone ADDRESS ...

  10. ReentrantLock 和 Condition的使用

    ReentrantLock  ReentrantLock可以等同于synchronized使用. ReentrantLock 类实现了Lock ,它拥有与 synchronized 相同的并发性和内存 ...