传送门

题意:定义一个无向图的权值为图中形为树的连通块数量的$k$次方,求所有$n$个点有标号的简单无向图的权值之和。

这个题还是很妙的啊……(好吧,其实只有最后的复合函数求导比较有意思……)

先套路一发,定义答案的$EGF$为$F(x)$一棵树的$EGF$为$T(x)$,每个连通块都不是树的$EGF$为$G(x)$,强制连通的无向图的$EGF$为$H(x)$,显然有

\begin{align}F(x)=\left(\sum_{i\ge 0}\frac{i^k T(x)^i}{i!}\right)G(x)\end{align}

意思就是枚举树的数量,统计数量之后乘上贡献,左边要除以$i!$是为了去重(因为几个树组成的图是集合,不是序列,元素没有顺序)。

根据一些简单的知识不难得到以下结论:

$[x^n]T(x)=n^{n-2}$

$G(x)=\exp(H(x)-T(x))$(因为每个连通块都不能是树,那么我们用连通图个数减掉树的个数,再用这个东西搞一个集合即可,不难发现就是对一个连通块的$EGF$做一下$\exp$的结果。)

$H(x)$可以跑多项式$\ln$之类的东西得到(参见城市规划的做法),那么后面的$G(x)$就好算了,然后再解决前面的那个东西就可以$O(n)$得出最后的答案了(因为只要求一项,所以暴力求出卷积的第$n$项即可)。

定义

\begin{align}A_k(x)=\sum_{i\ge 0}\frac{i^k T(x)^i}{i!}\end{align}

注意到$A_k(x)$其实是一个复合函数,那么假设有$f(T)=A_k(x)$,我们可以尝试对$f(T)$求个导,而根据复合函数求导法则($(f(g(x)))’=f’(g(x))g’(x)$)有$[T^i]f’(T)=\frac{i^k T(x)^{i-1}T'(x)i}{i!}=T'(x)\frac{i^{k+1}T(x)^{i-1}}{i!}$,因此$[T^i]f’(T)=\frac{i^k T(x)^{i-1}T'(x)i}{i!}=T'(x)\frac{i^{k+1}T(x)^{i-1}}{i!}$。

因为$f(T)$本质就是$A_k(x)$,因此$f’(T)$和$A_k’(x)$是等价的,所以有

\begin{align}A_k'(x)=\frac{T'(x)}{T(x)}\sum_{i\ge 1}\frac{i^{k+1}T(x)^i}{i!}=\frac{T'(x)}{T(x)}A_{k+1}(x)\end{align}

(注意这里不用处理常数项的问题,因为$k>0$时有$[x^0]A_k(x)=0$)

也就是说$A_{k+1}(x)=A_k'(x)\frac{T(x)}{T'(x)}$,那么直接利用这个递推$k$次即可,边界也不难得到:

\begin{align}A_0(x)=\sum_{i\ge 0}\frac{i^0 T(x)^i}{i!}=\exp(T(x))\end{align}

然后就可以做了,复杂度$O(kn\log n)$,因为$\exp$只需要做两次,所以常数还是不大的。

(虽然比起NTT优化DP的做法来说代码长还跑得慢……)

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,p=,g=;
void NTT(int*,int,int);
void getexp(int*,int*,int);
void getln(int*,int*,int);
void getinv(int*,int*,int);
void getderivative(int*,int*,int);
void getintegrate(int*,int*,int);
int qpow(int,int,int);
int n,N=,k,A[maxn],B[maxn],C[maxn],T[maxn],G[maxn],fac[maxn],fac_inv[maxn],inv[maxn],ans=;
int main(){
scanf("%d%d",&n,&k);
while(N<=n)N<<=;
fac[]=fac_inv[]=;
for(int i=;i<N;i++)fac[i]=(long long)fac[i-]*i%p;
fac_inv[N-]=qpow(fac[N-],p-,p);
for(int i=N-;i;i--)fac_inv[i]=(long long)fac_inv[i+]*(i+)%p;
for(int i=;i<N;i++)inv[i]=(long long)fac_inv[i]*fac[i-]%p;
T[]=G[]=;
for(int i=;i<=n;i++)T[i]=(long long)qpow(i,i-,p)*fac_inv[i]%p;
for(int i=;i<=n;i++)G[i]=(long long)qpow(,(((long long)i*(i-))>>)%(p-),p)*fac_inv[i]%p;
getln(G,B,N);
for(int i=;i<N;i++)B[i]=(B[i]-T[i]+p)%p;
getexp(B,G,N);
fill(B,B+(N<<),);
getderivative(T,B,N);
getinv(B,C,N);
copy(T,T+N,B);
NTT(B,N<<,);
NTT(C,N<<,);
for(int i=;i<(N<<);i++)C[i]=(long long)B[i]*C[i]%p;
NTT(C,N<<,-);
fill(C+N,C+(N<<),);
NTT(C,N<<,);
getexp(T,A,N);
for(int j=;j<=k;j++){
fill(B,B+(N<<),);
getderivative(A,B,N);
NTT(B,N<<,);
for(int i=;i<(N<<);i++)B[i]=(long long)B[i]*C[i]%p;
NTT(B,N<<,-);
copy(B,B+N,A);
}
for(int i=;i<=n;i++)ans=(ans+(long long)A[i]*G[n-i]%p)%p;
printf("%d",(int)((long long)ans*fac[n]%p));
return ;
}
void NTT(int *A,int n,int tp){
for(int i=,j=,k;i<n-;i++){
k=n;
do j^=(k>>=);while(j<k);
if(i<j)swap(A[i],A[j]);
}
for(int k=;k<=n;k<<=){
int wn=qpow(g,(tp>?(p-)/k:(p-)/k*(long long)(p-)%(p-)),p);
for(int i=;i<n;i+=k){
int w=;
for(int j=;j<(k>>);j++,w=(long long)w*wn%p){
int a=A[i+j],b=(long long)w*A[i+j+(k>>)]%p;
A[i+j]=(a+b)%p;
A[i+j+(k>>)]=(a-b+p)%p;
}
}
}
if(tp<){
int inv=qpow(n,p-,p);
for(int i=;i<n;i++)A[i]=(long long)A[i]*inv%p;
}
}
void getexp(int *A,int *C,int n){
static int B[maxn];
fill(C,C+(n<<),);
C[]=;
for(int k=;k<=n;k<<=){
getln(C,B,k);
for(int i=;i<k;i++)B[i]=(A[i]-B[i]+p)%p;
B[]=(B[]+)%p;
NTT(B,k<<,);
NTT(C,k<<,);
for(int i=;i<(k<<);i++)C[i]=(long long)B[i]*C[i]%p;
NTT(C,k<<,-);
fill(C+k,C+(k<<),);
}
}
void getln(int *A,int *C,int n){
static int B[maxn];
getderivative(A,B,n);
fill(B+n,B+(n<<),);
getinv(A,C,n);
NTT(B,n<<,);
NTT(C,n<<,);
for(int i=;i<(n<<);i++)B[i]=(long long)B[i]*C[i]%p;
NTT(B,n<<,-);
getintegrate(B,C,n);
fill(C+n,C+(n<<),);
}
void getinv(int *A,int *C,int n){
static int B[maxn];
fill(C,C+(n<<),);
C[]=qpow(A[],p-,p);
for(int k=;k<=n;k<<=){
copy(A,A+k,B);
fill(B+k,B+(k<<),);
NTT(B,k<<,);
NTT(C,k<<,);
for(int i=;i<(k<<);i++)C[i]=C[i]*((-(long long)C[i]*B[i]%p+p)%p)%p;
NTT(C,k<<,-);
fill(C+k,C+(k<<),);
}
}
void getderivative(int *A,int *C,int n){
for(int i=;i<n;i++)C[i-]=(long long)A[i]*i%p;
C[n-]=;
}
void getintegrate(int *A,int *C,int n){
for(int i=;i<n;i++)C[i]=(long long)A[i-]*inv[i]%p;
C[]=;
}
int qpow(int a,int b,int p){
int ans=;
for(;b;b>>=,a=(long long)a*a%p)if(b&)ans=(long long)ans*a%p;
return ans;
}

ps:代码里把每次乘的$\frac{T(x)}{T’(x)}$算出来之后直接存它的$DFT$了,这样每次乘的时候就只需要对$A_k(x)$做$DFT$和$IDFT$了,可以减小很多常数。

这个题给我的两点启发:

1.看见跟前面那半类似的式子就去试试求导和积分

2.牢记复合函数求导法则(论不学文化课的危害……)

hdu5824 graph的更多相关文章

  1. [开发笔记] Graph Databases on developing

    TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...

  2. Introduction to graph theory 图论/脑网络基础

    Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...

  3. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

  4. [LeetCode] Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  5. [LeetCode] Graph Valid Tree 图验证树

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  6. [LeetCode] Clone Graph 无向图的复制

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  7. 讲座:Influence maximization on big social graph

    Influence maximization on big social graph Fanju PPT链接: social influence booming of online social ne ...

  8. zabbix利用api批量添加item,并且批量配置添加graph

    关于zabbix的API见,zabbixAPI 1item批量添加 我是根据我这边的具体情况来做的,本来想在模板里面添加item,但是看了看API不支持,只是支持在host里面添加,所以我先在一个ho ...

  9. Theano Graph Structure

    Graph Structure Graph Definition theano's symbolic mathematical computation, which is composed of: A ...

随机推荐

  1. 关于android分辨率兼容问题

    关于手机分辨率相关术语和概念 屏幕尺寸:实际的物理尺寸,屏幕的对角线测量.为了方便,android把所有的屏幕尺寸分为了4个广义的大小:小,正常,大,特大. 屏幕密度:屏幕的物理面积内像素的数量,通常 ...

  2. 性能测试 vs 负载测试 vs 压力测试

    在做一些软件测试工作时,常常会被提及性能测试.负载测试.压力测试,这也是在软件测试方面最容易混淆的三个概念.之前和一个测试大牛聊天,他和我说常常面试一些测试人员会问一些这样的问题,大多人认为负载测试等 ...

  3. github常用项目汇总

    1.smartTable(智能表格) android自动生成表格框架 使用方法:在github中搜索smartTable 进入项目后,查看开源项目的介绍和使用方法即可.

  4. P4859 已经没有什么好害怕的了

    传送门 见计数想容斥 首先题目可以简单转化一下, 求 糖果比药片能量大的组数比药片比糖果能量大的组数多 $k$ 组 的方案数 因为所有能量各不相同,所以就相当于求 糖果比药片能量大的组数为 $(n+k ...

  5. 安装nagios出现的错误

    最近安装nagios时,检查的的状态都没有什么问题,就是监控系统的状态显示不出来 检测的结果如下: [root@lb02 ~]# /etc/init.d/httpd start Starting ht ...

  6. 贪心--cf、education62-C

    cf-Education 62-C 题目 C. Playlist time limit per test 2 seconds memory limit per test 256 megabytes i ...

  7. 使用NHibernate(5)-- Linq To NHibernate

    Linq是NHibernate所支持的查询语言之一,对于Linq的实现在源码的src/Linq目录下.以下是一个使用Linq进行查询数据的示例: var users = session.Query&l ...

  8. Map集合的四种遍历方式(转载)

    import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class TestMap { pu ...

  9. Elastic-Job源码分析之AbstractElasticJobExecutor分析

    还记得我们在JobScheduler中,在创建任务详情时,会调用一个建造器JobBuilder来创建一个Job,类型是LiteJob. LiteJob.java /** * Lite调度作业. * * ...

  10. 《python灰帽子》学习笔记:调试器设置

    一.构造 C  数据类型 C Type | Python Type | ctypes Type ____________________________________________________ ...