题意

给定一个\(n​\) 次的 \(f​\) 函数,向右移动 \(m​\) 次得到 \(g​\) 函数,第 \(i​\) 次移动长度是 \(a_i​\) ,求 \(g​\) 函数解析式的各项系数,对 \(998244353​\) 取模。

\(1 \leq n \leq 10^5\)

\(1\leq \sum m \leq 10^5\)

思路

设 \(\displaystyle S=-\sum_{i=1}^ma_i\)

\[g(x)=f(x+S)\\
g(x)=\sum_{i=0}^nc_i(x+S)^i\\
\]

二项展开后得到

\[g(x)=\sum_{i=0}^nc_i[\sum_{j=0}^i{i\choose j}S^{i-j}\cdot x^j]\\
\]

将 \(\displaystyle\sum_{j}\) 拉出,得到。

\[g(x)=\sum_{j=0}^n\sum_{i=j}^nc_i{i\choose j}S^{i-j}\cdot x^j\\
\]

那么多项式 \(g\) 的第 \(j\) 项 \(b_j\) 就是 \(\displaystyle\sum_{i=j}^nc_i{i\choose j}S^{i-j}\)

将组合数展开

\[b_j=\sum_{i=j}^nc_i S^{i-j}{i!\over j!(i-j)!}
\]

将只与 \(j\) 相关的项提出,合并变量相同的项得到

\[b_j={1\over j!}\sum_{i=j}^nc_ii!\cdot S^{i-j}{1\over (i-j)!}
\]

不难发现,右边有两项仅与 \(i\) 有关,有两项仅与 \(i-j\) 有关。

把式子写成卷积的形式

\[b_j={1\over j!}c_ii!\cdot S^{i-j}{1\over (i-j)!}
\]

用 \(i+j\) 替换 \(j\) 得到

\[b_{i+j}={1\over (i+j)!}c_ii!\cdot S^{-j}{1\over (-j)!}
\]

其中 \(i\in[0,n] ,j\in[-n,0],i+j\in[-n,n]\)

设 \(\displaystyle A_i=c_ii!,B_j=S^{-j}{1\over{(-j)!}}\)

那么就有了最终的表达式 \(\displaystyle b_{i+j}={1\over{i+j}}A_iB_j\)

对 \(A,B\) 两多项式进行卷积,最后乘上 \(\displaystyle {1\over {i+j}}\) 即可。

最后我们需要的只是 \(b\) 在 \([0,n]\) 的结果,多项式相乘一步,可以理解为:一组状态,每一个值都向一些方向转移一些值,用多项式表示就是一个状态多项式、一个转移多项式乘出一个结果多项式。关键是要保证所有状态的转移方向一致。

代码

#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
typedef long long ll;
using namespace std;
const int P=998244353,g=3;
const int N=1<<17|5;
namespace Maths
{
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b){x=1,y=0;return;}
exgcd(b,a%b,y,x),y-=a/b*x;
}
ll Pow(ll a,ll p,ll P)
{
ll res=1;
for(;p>0;p>>=1,(a*=a)%=P)if(p&1)(res*=a)%=P;
return res;
}
ll inv(ll a,ll P){ll x,y;exgcd(a,P,x,y);return (x%P+P)%P;}
};
using namespace Maths;
namespace _NTT
{
int A[N<<1],B[N<<1];
int r[N<<1];
void NTT(int *a,int p,int n)
{
FOR(i,0,n-1)if(i<r[i])swap(a[i],a[r[i]]);
for(int i=2;i<=n;i<<=1)
{
int wn=Pow(g,(P-1)/i,P);
if(p==-1)wn=inv(wn,P);
for(int j=0;j<n;j+=i)
{
int w=1;
for(int k=0;k<i/2;k++)
{
int u=a[j+k],t=(ll)w*a[j+k+i/2]%P;
a[j+k]=(u+t)%P,a[j+k+i/2]=(u-t)%P;
w=(ll)w*wn%P;
}
}
}
}
void multiply(const int *a,const int *b,int *c,int n1,int n2)
{
int n=1;
while(n<n1+n2-1)n<<=1;
FOR(i,0,n1-1)A[i]=a[i];
FOR(i,0,n2-1)B[i]=b[i];
FOR(i,n1,n-1)A[i]=0;
FOR(i,n2,n-1)B[i]=0;
FOR(i,0,n-1)r[i]=(r[i>>1]>>1)|((i&1)*(n>>1)); NTT(A,1,n),NTT(B,1,n);
FOR(i,0,n-1)A[i]=(ll)A[i]*B[i]%P;
NTT(A,-1,n);
int I=inv(n,P);
FOR(i,0,n1+n2-2)c[i]=(ll)A[i]*I%P;
}
};
int A[N],B[N],C[N<<2];
int fac[N],c[N],S;
int n,m; int main()
{
fac[0]=1;FOR(i,1,N-1)fac[i]=(ll)fac[i-1]*i%P;
while(~scanf("%d",&n))
{
FOR(i,0,n)scanf("%d",&c[i]);
scanf("%d",&m);
S=0;
while(m--)
{
int x;
scanf("%d",&x);
S-=x;
if(S<0)S+=P;
}
FOR(i,0,n)A[i]=(ll)c[i]*fac[i]%P;
FOR(i,-n,0)B[i+n]=Pow(S,-i,P)*inv(fac[-i],P)%P;
_NTT::multiply(A,B,C,n+1,n+1);
FOR(i,0,n)printf("%lld ",(C[i+n]*inv(fac[i],P)%P+P)%P);
puts("");
}
return 0;
}

HDU 6061 RXD and functions(NTT)的更多相关文章

  1. 【推导】【NTT】hdu6061 RXD and functions(NTT)

    题意:给定一个n次多项式f(x)的各项系数,让你求f(x-Σai)的各项系数. http://blog.csdn.net/v5zsq/article/details/76780053 推导才是最关键的 ...

  2. 2017 Multi-University Training Contest - Team 3 RXD and functions(NTT)

    题解: 我是参考的 http://blog.csdn.net/qq_32570675/article/details/76571666 这一篇 orz 原来可以这么变换,涨姿势 代码: #includ ...

  3. 2017 多校3 hdu 6061 RXD and functions

    2017 多校3 hdu 6061 RXD and functions(FFT) 题意: 给一个函数\(f(x)=\sum_{i=0}^{n}c_i \cdot x^{i}\) 求\(g(x) = f ...

  4. HDU 6061 - RXD and functions | 2017 Multi-University Training Contest 3

    每次NTT都忘记初始化,真的是写一个小时,Debug两个小时- - /* HDU 6061 - RXD and functions [ NTT ] | 2017 Multi-University Tr ...

  5. HDU 6061 RXD and functions NTT

    RXD and functions Problem Description RXD has a polynomial function f(x), f(x)=∑ni=0cixiRXD has a tr ...

  6. hdu 1080 Human Gene Functions(DP)

    题意: 人类基因由A.C.G.T组成. 有一张5*5的基因表.每格有一个值,叫相似度.例:A-C:-3.意思是如果A和C配对, 则它俩的相似度是-3[P.S.:-和-没有相似度,即-和-不能配对] 现 ...

  7. HDU 5829 Rikka with Subset(NTT)

    题意 给定 \(n\) 个数 \(a_1,a_2,\cdots a_n\),对于每个 \(K\in[1,n]\) ,求出 \(n\) 个数的每个子集的前 \(K\) 大数的和,输出每个值,对 \(99 ...

  8. HDU 6061 RXD and functions

    题目链接:HDU-6061 题意:给定f(x),求f(x-A)各项系数. 思路:推导公式有如下结论: 然后用NTT解决即可. 代码: #include <set> #include < ...

  9. HDU 6060 RXD and dividing(LCA)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6060 [题目大意] 给一个n个节点的树,要求将2-n号节点分成k部分, 然后将每一部分加上节点1, ...

随机推荐

  1. sitecore系统教程之默认收集数据库MongoDB注意事项

    MongoDB是一个高度可扩展的基于文档的NoSQL数据库解决方案,Sitecore体验数据库(xDB)用于收集数据库.在安装MongoDB之前,您应该考虑以下事项: 确定您是需要基于公共云的解决方案 ...

  2. Java Redis JNI

    基本参考菜鸟教程,java下载直接安装,注意文件名和类名需要一致的问题: redis下载以后按菜鸟教程linux下安装,方式编译运行ok: Java使用redis按菜鸟教程下载.jar,保存在本地某个 ...

  3. 设计模式之Memento(备忘机制)(转)

    Memento定义: memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public clas ...

  4. Linux基础命令---管理组gpasswd

    gpasswd gpasswd指令用来管理组文件“/etc/group”和“/etc/gshadow”,每个组可以设置管理员.组员.密码.系统管理员可以使用-A选项定义组管理员,使用-M选项定义成员. ...

  5. 转:wcf大文件传输解决之道(1)

    首先声明,文章思路源于MSDN中徐长龙老师的课程整理,加上自己的一些心得体会,先总结如下: 在应对与大文件传输的情况下,因为wcf默认采用的是缓存加载对象,也就是说将文件包一次性接受至缓存中,然后生成 ...

  6. redis安装集群的2种方式

    redis主从只是数据的备份,当主宕机后不会自动切换从为主,需要手动切换从为主. 哨兵就可以自动切换从为主, 当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以 ...

  7. C++ 开源库列表

    https://zh.cppreference.com/w/cpp/links/libs

  8. Prometheus监控学习笔记之PromQL 内置函数

    概述 Prometheus 提供了其它大量的内置函数,可以对时序数据进行丰富的处理.某些函数有默认的参数,例如:year(v=vector(time()) instant-vector).其中参数 v ...

  9. MySQL按指定字段自定义列表排序

    亲测实例: 1级排序:同城>异城 2级排序:未领养>以领养 3级排序:发布最新靠前 MYSQL语句如下: SELECT ura.id,ura.city,ura.uid,ura.rescue ...

  10. flask模板,路由,消息提示,异常处理

    1.flask的路由与反向路由 from flask import Flask, request, url_for app = Flask(__name__) @app.route('/') def ...