并不对劲的多项式求ln,exp
ln
解释
设\(g(x)=ln(f(x))\),两边同时求导,则有:\(g'(x)=ln'(f(x))*f'(x)=f^{-1}(x)*f'(x)\)(1)
因为\(f(x)\)是个多项式,所以设\(f(x)=\sum_{i=0}^{n}a_i*x^i\),则有\(f'(x)=\sum_{i=0}^{n-1}a_{i+1}*(i+1)*x^i\)
设\(h(x)=f^{-1}(x)*f'(x)\),对(1)式两边同时求积分,得:\(g(x)=\int h(x)\space dx\)
因为\(h(x)\)是个多项式,设\(h(x)=\sum_{i=0}^{n}b_i*x^i\)就有:\(\int h(x)\space dx=\sum_{i=1}^{n}\frac{b_{i-1}}{i}x^i\)
代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 800010
#define LL long long
#define mo(x) (x>=mod?x-mod:(x<0?x+mod:x))
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
return;
}
const LL mod=998244353;
int f[maxn],g[maxn],h[maxn],nowlen,nown,r[maxn],tmp[maxn],n;
int mul(int x,int y){int res=1;while(y){if(y&1)res=(LL)res*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return res;}
void dnt(int * u,int fh)
{
rep(i,0,nown-1)r[i]=(r[i>>1]>>1)|((i&1)<<(nowlen-1));
rep(i,0,nown-1)if(i<r[i])swap(u[i],u[r[i]]);
for(int i=1;i<nown;i<<=1)
{
int wn=mul(3,(mod-1)/(i<<1));
if(fh==-1)wn=mul(wn,mod-2);
for(int j=0;j<nown;j+=(i<<1))
{
int w=1;
rep(k,0,i-1){int x=u[j+k],y=(LL)w*(LL)u[i+j+k]%mod;u[j+k]=mo(x+y),u[i+j+k]=mo(x-y),w=(LL)w*(LL)wn%mod;}
}
}
if(fh==-1)
{
int inv=mul(nown,mod-2);
rep(i,0,nown-1)u[i]=(LL)u[i]*(LL)inv%mod;
}
}
void getny(int * u,int * v,int nlen)
{
v[0]=mul(u[0],mod-2);
for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
{
nown=tmpn<<1,nowlen=len+1;
rep(i,0,nown-1)tmp[i]=u[i];
nown<<=1,nowlen++;
rep(i,(tmpn<<1),nown-1)tmp[i]=0;
dnt(tmp,1),dnt(v,1);
rep(i,0,nown-1)v[i]=mo(2ll-(LL)tmp[i]*(LL)v[i]%mod)*(LL)v[i]%mod;
dnt(v,-1);
rep(i,(tmpn<<1),nown-1)v[i]=0;
}
rep(i,nlen,nown)v[i]=0;
}
void getup(int * u,int * v,int nlen)
{
rep(i,1,nlen-1)v[i-1]=(LL)i*(LL)u[i]%mod;v[nlen-1]=0;
}
void getdx(int * u,int * v,int nlen)
{
rep(i,1,nlen-1)v[i]=(LL)u[i-1]*(LL)mul(i,mod-2)%mod;v[0]=0;
}
void getln(int * u,int nlen)
{
getup(u,h,nlen),getny(u,g,nlen);
for(nowlen=0,nown=1;nown<(nlen+nlen);nowlen++,nown<<=1);
dnt(h,1),dnt(g,1);
rep(i,0,nown-1)h[i]=(LL)h[i]*(LL)g[i]%mod;
rep(i,0,nown-1)g[i]=0;
dnt(h,-1);getdx(h,g,nlen);
rep(i,nlen,nown)g[i]=0;
}
int main()
{
n=read();
rep(i,0,n-1)f[i]=read();
getln(f,n);
rep(i,0,n-1)write(g[i]),putchar(' ');
return 0;
}
exp
解释
这个人(点这里)讲得很清楚
代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 800010
#define LL long long
#define mo(x) (x>=mod?x-mod:(x<0?x+mod:x))
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
return;
}
const LL mod=998244353;
int f[maxn],g[maxn],h[maxn],ans[maxn],nowlen,nown,r[maxn],tmp[maxn],tmp2[maxn],n;
int mul(int x,int y){int res=1;while(y){if(y&1)res=(LL)res*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return res;}
void dnt(int * u,int fh)
{
rep(i,0,nown-1)r[i]=(r[i>>1]>>1)|((i&1)<<(nowlen-1));
rep(i,0,nown-1)if(i<r[i])swap(u[i],u[r[i]]);
for(int i=1;i<nown;i<<=1)
{
int wn=mul(3,(mod-1)/(i<<1));
if(fh==-1)wn=mul(wn,mod-2);
for(int j=0;j<nown;j+=(i<<1))
{
int w=1;
rep(k,0,i-1){int x=u[j+k],y=(LL)w*(LL)u[i+j+k]%mod;u[j+k]=mo(x+y),u[i+j+k]=mo(x-y),w=(LL)w*(LL)wn%mod;}
}
}
if(fh==-1)
{
int inv=mul(nown,mod-2);
rep(i,0,nown-1)u[i]=(LL)u[i]*(LL)inv%mod;
}
}
void getny(int * u,int * v,int nlen)
{
v[0]=mul(u[0],mod-2);
for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
{
nown=tmpn<<1,nowlen=len+1;
rep(i,0,nown-1)tmp[i]=u[i];
nown<<=1,nowlen++;
rep(i,(tmpn<<1),nown-1)tmp[i]=0;
dnt(tmp,1),dnt(v,1);
rep(i,0,nown-1)v[i]=mo(2ll-(LL)tmp[i]*(LL)v[i]%mod)*(LL)v[i]%mod;
dnt(v,-1);
rep(i,(tmpn<<1),nown-1)v[i]=0;
}
rep(i,0,nown)tmp[i]=0;
rep(i,nlen,nown)v[i]=0;
}
void getup(int * u,int * v,int nlen)
{
rep(i,1,nlen-1)v[i-1]=(LL)i*(LL)u[i]%mod;v[nlen-1]=0;
}
void getdx(int * u,int * v,int nlen)
{
rep(i,1,nlen-1)v[i]=(LL)u[i-1]*(LL)mul(i,mod-2)%mod;v[0]=0;
}
void getln(int * u,int * v,int nlen)
{
getup(u,h,nlen),getny(u,g,nlen);
for(nowlen=0,nown=1;nown<(nlen+nlen);nowlen++,nown<<=1);
dnt(h,1),dnt(g,1);
rep(i,0,nown-1)h[i]=(LL)h[i]*(LL)g[i]%mod;
rep(i,0,nown-1)g[i]=0;
dnt(h,-1);getdx(h,v,nlen);
rep(i,nlen,nown)v[i]=0;
}
void getexp(int * u,int * v,int nlen)
{
rep(i,0,(nlen<<2))v[i]=0;
v[0]=1;
for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
{
rep(i,0,(tmpn<<1))tmp2[i]=0;
getln(v,tmp2,(tmpn<<1));
nown=(tmpn<<2),nowlen=len+2;
rep(i,(tmpn<<1),nown)tmp2[i]=0;
rep(i,0,(tmpn<<1)-1)tmp[i]=u[i];
rep(i,(tmpn<<1),nown)tmp[i]=0;
dnt(tmp2,1),dnt(v,1),dnt(tmp,1);
rep(i,0,nown-1)v[i]=(LL)v[i]*(LL)mo(mo(1ll-tmp2[i])+tmp[i])%mod;
dnt(v,-1);
rep(i,(tmpn<<1),nown)v[i]=0;
}
rep(i,nlen,nown)v[i]=0;
}
int main()
{
n=read();
rep(i,0,n-1)f[i]=read();
getexp(f,ans,n);
rep(i,0,n-1)write(ans[i]),putchar(' ');
return 0;
}
并不对劲的多项式求ln,exp的更多相关文章
- 多项式求ln,求exp,开方,快速幂 学习总结
按理说Po姐姐三月份来讲课的时候我就应该学了 但是当时觉得比较难加上自己比较懒,所以就QAQ了 现在不得不重新弄一遍了 首先说多项式求ln 设G(x)=lnF(x) 我们两边求导可以得到G'(x)=F ...
- [BZOJ3456]城市规划(生成函数+多项式求逆+多项式求ln)
城市规划 时间限制:40s 空间限制:256MB 题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一 ...
- BZOJ 3456: 城市规划 [多项式求逆元 组合数学 | 生成函数 多项式求ln]
3456: 城市规划 题意:n个点组成的无向连通图个数 以前做过,今天复习一下 令\(f[n]\)为n个点的无向连通图个数 n个点的完全图个数为\(2^{\binom{n}{2}}\) 和Bell数的 ...
- 指数型生成函数 及 多项式求ln
指数型生成函数 我们知道普通型生成函数解决的是组合问题,而指数型生成函数解决的是排列问题 对于数列\(\{a_n\}\),我们定义其指数型生成函数为 \[G(x) = a_0 + a_1x + a_2 ...
- BZOJ3456 城市规划 【多项式求ln】
题目链接 BZOJ3456 题解 真是一道经典好题,至此已经写了分治\(NTT\),多项式求逆,多项式求\(ln\)三种写法 我们发现我们要求的是大小为\(n\)无向联通图的数量 而\(n\)个点的无 ...
- 【BZOJ】3456: 城市规划(多项式求ln)
题解 在我写过分治NTT,多项式求逆之后 我又一次写了多项式求ln 我们定义一个数列的指数型生成函数为 \(\sum_{i = 0}^{n} \frac{A_{i}}{i!} x^{i}\) 然后这个 ...
- 【BZOJ3456】轩辕朗的城市规划 EGF+多项式求ln
我们构造$f(i)$和$g(i)$. 其中$f(x)$表示由$x$个节点构成的无向简单连通图的个数. $g(x)$表示有$x$个节点构成的无向简单图(不要求连通)的个数. 显然,由$x$个节点构成的无 ...
- 洛谷5月月赛T30212 玩游戏 【分治NTT + 多项式求ln】
题目链接 洛谷T30212 题解 式子很容易推出来,二项式定理展开后对于\(k\)的答案即可化简为如下: \[k!(\sum\limits_{i = 0}^{k} \frac{\sum\limits_ ...
- bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...
随机推荐
- Word文档转Markdown插件(Windows)
在线的转换,Shell脚本的转换都试过了,都没有原生Word文档集成的插件转换这么好用,并且没有Bug. 下载:http://www.writage.com/
- 使用 Git + Dropbox + SourceTree 做 Source Code Management
此篇文章主要針對有安裝 XCode 的 Mac 用戶. Git 版本控管工具,作用類似 CVS.Subversion(簡 稱SVN),好處在於 Git 不像 CVS 及 SVN 是屬於集中式的版本控管 ...
- 社会信息化环境下的IT新战略
我们现在所处的信息化环境正在发生改变,技术已经成为影响组织的最重要的外部力量,传统的正金字塔的结构被移动互联网深深改变:员工能够更加自由的获取信息,变成更多的信息链接,这种链接不光连接人和组织,还连接 ...
- MongoDB下配置用户权限
MongoDB默认设置为无权限訪问限制 注:研究成果基于Windows平台 在部署mongodb成功后.进入控制台: 输入命令:mongod use admin,你会发现该DB下包括了一个syste ...
- BUPT复试专题—最近公共祖先(2014软院)
题目描述 给出一棵有N个节点的有根树TREE(根的编号为1),对于每组查询,请输出树上节点u和v的最近公共祖先. 最近公共祖先:对于有向树TREE的两个结点u,v.最近公共祖先LCA(TREE u,v ...
- 步步为营(十六)搜索(二)BFS 广度优先搜索
上一篇讲了DFS,那么与之相应的就是BFS.也就是 宽度优先遍历,又称广度优先搜索算法. 首先,让我们回顾一下什么是"深度": 更学术点的说法,能够看做"单位距离下,离起 ...
- 从机器码理解RIP 相对寻址
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/rip-relative-addressing 本博客同步在 ...
- 小程序 - tabBar
Tips:如果网页图片(文字)看不清,请按CTRL+鼠标滚轮 1.建议使用阿里图库 或者 easyicon 2.建议使用81*81且低于40KB的图片(建议jpg) 3.如需查看脑图结构,请点击:ta ...
- node 爬虫 --- 批量下载图片
步骤一:创建项目 npm init 步骤二:安装 request,cheerio,async 三个模块 request 用于请求地址和快速下载图片流. https://github.com/reque ...
- HDU 3420 Bus Fair [补]
今天玩魔灵玩多了,耽误了时间,回去宿舍又没电. /*********************************************/ Bus Fair Time Limit: 2000/10 ...