由于菜鸡的我实在是没学会上升幂下降幂那一套理论,这里用的是完全普通多项式的做法。

要是有大佬愿意给我讲讲上升幂下降幂那一套东西,不胜感激orz!

首先可以想到prufer序列,如果不会的话可以左转百度。

我们把答案写成prufer序列的形式,这样的话他的贡献是固定的,其中$d_i$表示$i$的出现次数。

$ans = (n-2)! \prod_{i=1}^n \frac{a_i^{d_i+1}}{d_i!}$

把原来的柿子带进来

$ans = \sum_{\sum d_i = n-2} (n-2)! \sum_{i=1}^n a_i^{d_i+1} d_i^m\prod_{j=1}\frac{d_j^m}{d_j!}$

把相同的因数提出来

$ans =(n-2)! \prod_{i=1}^n a_i \sum_{\sum d_i = n-2} \sum_{i=1}^n a_i^{d_i} d_i^m\prod_{j=1}\frac{d_j^m}{d_j!}$

考虑后面的

$ans' = \sum_{\sum d_i = n-2} \sum_{i=1}^n a_i^{d_i} d_i^m\prod_{j=1}\frac{d_j^m}{d_j!}$

为了方便写成生成函数形式,把柿子化成这样

$ans' = \sum_{\sum d_i = n-2} \sum_{i=1}^n \frac{a_i^{d_i} d_i^{2m}}{d_i!}\prod_{j=1,j\neq i}\frac{d_j^m}{d_j!} $

$A(x)=\sum_{i=0}^n \frac{i^{2m}}{i!} x^i$

$B(x)=\sum_{i=0}^n \frac{i^m}{i!} x^i$

把它们带进去

$ans '=\sum_{i=1}^n A(a_i) \prod_{j=1,j\neq i}^n B(a_j) \\ = \sum_{i=1}^n \frac{A}{B}(a_i) \prod_{j=1}^n B(a_j)$

对于$\prod B(a_i)$ 根据常见套路,写成$exp(\sum ln(B(a_i)))$ 当然$\frac{A}{B}$也是这么处理。

接下来我们就遇到了更常见的,求$\sum_{i=1}^{n} a_i^k$ 也就是求数列幂和。

这个东西可以戳这里:qwq (额 需要密码,如果你需要的话可以戳我QQ)

这里简略的说一下,就是我们有$F(x)=\sum(a_1^i+...+a_n^i)x^i$ 可以化成这样$F(x) = \sum (a_ix+...+a_i^nx^n)$ 进而写成这样$F(x) = \sum \frac{a_i}{1-a_ix}$

我们令$G(x) = \prod (1-a_ix)$ 所以有$F = -ln'(G)$

对于$G$来说,我们可以直接分治FFT,然后F就可以poly_ln来求

其余的就是写一个多项式全家桶就可以了。

啊,多项式真有趣。

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define mdn 998244353
#define G 3
#define N 400100
using namespace std;
int read()
{
int s=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-; ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return f*s;
}
int fac[N],inv[N];
int Inv(int x){return 1ll*inv[x]*fac[x-]%mdn;}
void upd(int &x,int y){x+=x+y>=mdn?y-mdn:y;}
int ksm(int bs,int mi)
{
int ans=;
while(mi)
{
if(mi&) ans=1ll*ans*bs%mdn;
bs=1ll*bs*bs%mdn; mi>>=;
}
return ans;
}
int r[N];
int init(int n)
{
int l=,lim=;
while(lim<n) lim<<=,l++;
for(int i=;i<lim;i++)
r[i]=(r[i>>]>>)|((i&)<<l-);
return lim;
}
void ntt(int *a,int lim,int f)
{
for(int i=;i<lim;i++) if(r[i]>i)
swap(a[r[i]],a[i]);
for(int k=,mid=;k<=lim;k<<=,mid<<=)
{
int Wn=ksm(G,(mdn-)/k); if(f) Wn=ksm(Wn,mdn-);
for(int w=,i=;i<lim;i+=k,w=) for(int j=;j<mid;j++,w=1ll*w*Wn%mdn)
{
int x=a[i+j],y=1ll*w*a[i+mid+j]%mdn;
a[i+j]=(x+y)%mdn; a[i+mid+j]=(mdn+x-y)%mdn;
}
}
if(f) for(int kinv=ksm(lim,mdn-),i=;i<lim;i++)
a[i]=1ll*a[i]*kinv%mdn;
}
int poly_mul(int *a,int *b,int *c,int n)
{
int lim=init(n<<);
ntt(a,lim,); ntt(b,lim,);
for(int i=;i<lim;i++) c[i]=1ll*a[i]*b[i]%mdn;
ntt(c,lim,); return lim;
}
int tmp[N];
void poly_inv(int *a,int *ans,int n)
{
if(n==){ans[]=ksm(a[],mdn-); return;}
int mid=n+>>; poly_inv(a,ans,mid);
int lim=init(n<<);
for(int i=;i<n;i++) tmp[i]=a[i];
for(int i=n;i<lim;i++) tmp[i]=;
ntt(tmp,lim,); ntt(ans,lim,);
for(int i=;i<lim;i++)
ans[i]=(2ll-1ll*tmp[i]*ans[i]%mdn+mdn)*ans[i]%mdn;
ntt(ans,lim,);
for(int i=n;i<lim;i++) ans[i]=;
}
int tmp2[N];
void poly_ln(int *a,int *ans,int n)
{
poly_inv(a,tmp2,n);
for(int i=;i<n;i++) ans[i]=1ll*a[i+]*(i+)%mdn;
int lim=poly_mul(tmp2,ans,tmp2,n); tmp2[n-]=;
for(int i=;i<n;i++) ans[i]=1ll*tmp2[i-]*Inv(i)%mdn,tmp2[i-]=;
for(int i=n;i<lim;i++) ans[i]=tmp2[i]=;
ans[]=;
}
int tmp3[N],tmp4[N];
void poly_exp(int *a,int *ans,int n)
{
if(n==){ans[]=; return;}
int mid=n+>>; poly_exp(a,ans,mid);
for(int i=;i<(n<<);i++) tmp2[i]=tmp3[i]=;
for(int i=;i<n;i++) tmp4[i]=a[i]; poly_ln(ans,tmp3,n);
int lim=init(n<<);
ntt(tmp3,lim,); ntt(tmp4,lim,); ntt(ans,lim,);
for(int i=;i<lim;i++)
ans[i]=1ll*(tmp4[i]-tmp3[i]++mdn)%mdn*ans[i]%mdn;
ntt(ans,lim,);
for(int i=n;i<lim;i++) ans[i]=tmp4[i]=;
}
int tmp5[N],tmp6[N];
void solve(int *a,int l,int r)
{
if(l==r) return;
int mid=l+r>>;
solve(a,l,mid); solve(a,mid+,r);
int d=r-l+;
for(int i=l;i<=mid;i++) tmp5[i-l+]=a[i];
for(int i=mid+;i<=r;i++) tmp6[i-mid]=a[i];
tmp5[]=tmp6[]=;
int lim=poly_mul(tmp5,tmp6,tmp5,d);
for(int i=;i<d;i++) a[l+i]=tmp5[i+];
for(int i=;i<=lim;i++) tmp5[i]=tmp6[i]=;
}
void prework(int n)
{
n++; fac[]=;
for(int i=;i<=n;i++) fac[i]=1ll*fac[i-]*i%mdn;
inv[n]=ksm(fac[n],mdn-);
for(int i=n;i;i--) inv[i-]=1ll*inv[i]*i%mdn;
}
int a[N],f[N],n,m,g[N],A[N],B[N],in[N],fr[N],ls[N];
int main()
{
n=read(),m=read(); prework(n);
for(int i=;i<=n;i++) a[i]=read(),f[i]=(mdn-a[i])%mdn;
solve(f,,n); f[]=; poly_ln(f,g,n+);
for(int i=;i<=n;i++) f[i]=1ll*g[i+]*(i+)%mdn;
for(int i=n;i;i--) f[i]=(-f[i-]+mdn)%mdn; f[]=n;
for(int i=;i<=n;i++)
{
A[i]=1ll*ksm(i+,*m)*inv[i]%mdn;
B[i]=1ll*ksm(i+,m)*inv[i]%mdn;
}
int lim=init(n<<|);
poly_ln(B,g,n+); poly_inv(B,in,n+);
for(int i=;i<n;i++) g[i]=1ll*g[i]*f[i]%mdn;
for(int i=n;i<lim;i++) g[i]=in[i]=;
poly_exp(g,ls,n);
for(int i=n;i<lim;i++) ls[i]=;
poly_mul(A,in,fr,n);
for(int i=;i<n;i++) fr[i]=1ll*fr[i]*f[i]%mdn;
for(int i=n;i<lim;i++) fr[i]=;
poly_mul(fr,ls,f,n);
int ans=fac[n-];
for(int i=;i<=n;i++) ans=1ll*ans*a[i]%mdn;
ans=1ll*ans*f[n-]%mdn;
printf("%d\n",ans);
return ;
}

LOJ2320「清华集训 2017」生成树计数的更多相关文章

  1. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

  2. 【LOJ】#2320. 「清华集训 2017」生成树计数

    题解 我,理解题解,用了一天 我,卡常数,又用了一天 到了最后,我才发现,我有个加法取模,写的是while(c >= MOD) c -= MOD 我把while改成if,时间,少了 六倍. 六倍 ...

  3. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  4. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  5. Loj #2321. 「清华集训 2017」无限之环

    Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...

  6. loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主

    #2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较   题目描述 "A fight? Co ...

  7. [LOJ#2330]「清华集训 2017」榕树之心

    [LOJ#2330]「清华集训 2017」榕树之心 试题描述 深秋.冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子.相识数年的Evan和Lyra再次回到了小时候见面的茂盛榕树之下.小溪依旧 ...

  8. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...

  9. [LOJ#2328]「清华集训 2017」避难所

    [LOJ#2328]「清华集训 2017」避难所 试题描述 "B君啊,你当年的伙伴都不在北京了,为什么你还在北京呢?" "大概是因为出了一些事故吧,否则这道题就不叫避难所 ...

随机推荐

  1. Mysql基本管理知识

    数据库的启动 [root@node80 ~]# /etc/init.d/mysqld start #mysqld是从安装包拷贝的mysql.server Starting MySQL. SUCCESS ...

  2. Delphi XE2 之 FireMonkey 入门(32) - 数据绑定: TBindingsList: TBindList、TBindPosition [未完成...]

    Delphi XE2 之 FireMonkey 入门(32) - 数据绑定: TBindingsList: TBindList.TBindPosition [未完成...] //待补...

  3. nginx排查502错误

    排查502错误1.查看/usr/local/nginx/conf/nginx.conf从而知道其错误日志在哪.重点查看其错误日志.2.如果是/tmp/dd.sock2017/05/01 18:48:3 ...

  4. 阶段1 语言基础+高级_1-3-Java语言高级_09-基础加强_第3节 注解_18_注解_案例_简单的测试框架

    定义计算器的类 用注解的方式去测试计算器类里面 所有的方法 想验证哪个方法 就在方法的上面加上注解@check 执行TestCheck验证方法 控制台的输出 根目录生成了一个 bug.txt文件 重写 ...

  5. JavaSE部分1.Java基础

    1.为什么重写equals()还要重写hashcode()?  (equals()和hashCode()是java Object中两个基本方法) 首先equals与hashcode间的关系是这样的: ...

  6. 测开之路一百二十六:flask之获取request请求数据

    可以根据flask的request对象获取所有的请求信息 path = request.path # 获取请求地址method = request.method # 获取请求方法ip = reques ...

  7. Eclipse与Tomcat

    新进一个Web项目,有些小坎坷,于是引发了对于Eclipse和Tomcat的配置关系的思考. 首先提及一点当年的观点:Tomcat是一个容器,所有的功能都是以插件的形式放入其中:比如tomcat就是o ...

  8. flutter dialog异常Another exception was thrown: Navigator operation requested with a context that does not include a Navigator

    我在使用flutter里的对话框控件的时候遇到了一个奇怪的错误 Another exception was thrown: Navigator operation requested with a c ...

  9. Java——HashMap源码解析

    以下针对JDK 1.8版本中的HashMap进行分析. 概述     哈希表基于Map接口的实现.此实现提供了所有可选的映射操作,并且允许键为null,值也为null.HashMap 除了不支持同步操 ...

  10. 20191127 Spring Boot官方文档学习(9.1-9.3)

    9."使用方法"指南 9.1.Spring Boot应用程序 9.1.1.创建自己的FailureAnalyzer FailureAnalyzer被包装在FailureAnalys ...