link

题意简述

给定一颗无根树,对于所有大小为 $i$ 的点集,求出能够包含它的所有联通块之和,定义为 $f_i$ ,答案对 $924844033$ 取模。

$n\leq 2\times 10^5$ 。

$solution:$

考虑每个点在点集中起到的贡献,可以得到

$$f_i=n\times\dbinom{n}{k}-\sum_{i=1}^n \dbinom{n-size_i}{k}+\sum_{x\in i} \dbinom{size_x}{k}\\=n\times \dbinom{n}{k}-\sum_{i=k}^n cnt_i\dbinom{i}{k}\\=n\times \dbinom{n}{k}-\dfrac{1}{k}\sum_{i=k}^n \dfrac{i!}{(i-k)}$$

设 $a_i=cnt_i\times i!,b_i=(n-i)!$ 。

$$f_i=n\times \dbinom{n}{k}-\sum_{i=k}^n a_i\times b_{n-i+k}$$

直接 $NTT$ 即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define int long long
#define mod 924844033
using namespace std;
inline int read(){
int f=,ans=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
const int MAXN=;
int n,inv[MAXN],head[MAXN],fac[MAXN],infac[MAXN],Cnt,cnt[MAXN],siz[MAXN];
int C(int n,int m){return (((fac[n]*infac[m])%mod)*infac[n-m])%mod;}
struct node{
int u,v,nex;
}x[MAXN<<];
void add(int u,int v){
x[Cnt].u=u,x[Cnt].v=v,x[Cnt].nex=head[u],head[u]=Cnt++;
}
int ksm(int a,int b){
int ans=;
while(b){
if(b&) ans*=a,ans%=mod;
a*=a,a%=mod;
b>>=;
}return ans;
}
void dfs(int u,int fath){
siz[u]=;
for(int i=head[u];i!=-;i=x[i].nex){
if(x[i].v==fath) continue;
dfs(x[i].v,u);
siz[u]+=siz[x[i].v];
cnt[siz[x[i].v]]++;
}
cnt[n-siz[u]]++;
return;
}
int N,M,flip[MAXN],f[MAXN],g[MAXN];
void NTT(int *f,int opt){
for(int i=;i<N;i++) if(i<flip[i]) swap(f[i],f[flip[i]]);
for(int p=;p<=N;p<<=){
int len=p>>,buf=ksm(,(mod-)/p);
if(opt==-) buf=ksm(buf,mod-);
for(int be=;be<N;be+=p){
int tmp=;
for(int l=be;l<be+len;l++){
int t=f[l+len]*tmp;t%=mod;
f[l+len]=(f[l]-t+mod)%mod,f[l]=(f[l]+t)%mod;
tmp*=buf,tmp%=mod;
}
}
}
if(opt==-){
int inv=ksm(N,mod-);
for(int i=;i<N;i++) f[i]*=inv,f[i]%=mod;
}return;
}
signed main(){
// freopen("6.in","r",stdin);
memset(head,-,sizeof(head));
inv[]=;for(int i=;i<=;i++) inv[i]=((mod-mod/i)*inv[mod%i])%mod;
fac[]=;for(int i=;i<=;i++) fac[i]=(fac[i-]*i)%mod;
infac[]=;for(int i=;i<=;i++) infac[i]=(infac[i-]*inv[i])%mod;
n=read();
for(int i=;i<n;i++){
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs(,);
N=n,M=n;
for(int i=;i<=N;i++) f[i]=(cnt[i]*fac[i])%mod;
for(int i=;i<=M;i++) g[i]=infac[n-i];
M+=N;
for(N=;N<=M;N<<=);
for(int i=;i<N;i++) flip[i]=((flip[i>>]>>)|(i&?N>>:));
NTT(f,),NTT(g,);
for(int i=;i<N;i++) f[i]*=g[i],f[i]%=mod;
NTT(f,-);
for(int i=;i<=n;i++){
int a=(n*C(n,i))%mod,b=(infac[i]*f[n+i])%mod;
printf("%lld\n",(((a-b)%mod)+mod)%mod);
}return ;
}

[AGC005F] Many Easy Problems的更多相关文章

  1. AGC005F Many Easy Problems(NTT)

    先只考虑求某个f(k).考虑转换为计算每条边的贡献,也即该边被所选连通块包含的方案数.再考虑转换为计算每条边不被包含的方案数.这仅当所选点都在该边的同一侧.于是可得f(k)=C(n,k)+ΣC(n,k ...

  2. 【AtCoder】AGC005F - Many Easy Problems

    题解 我们把一个点的贡献转化为一条边的贡献,因为边的数量是点的数量-1,最后再加上选点方案数\(\binom{n}{k}\)即可 一条边的贡献是\(\binom{n}{k} - \binom{a}{k ...

  3. 解题:AT2064 Many Easy Problems&EXNR #1 T3 两开花

    题面 两道题比较像,放在一起写了,后者可以看成前者的加强版 (sto ztb orz) 先看AT那道题 考虑计算每个点的贡献,用容斥计算:每个点没有贡献当且仅当选的所有点都在以他为根时的一个子节点的子 ...

  4. Codeforces 913D - Too Easy Problems

    913D - Too Easy Problems 思路:二分check k 代码: #include<bits/stdc++.h> using namespace std; #define ...

  5. 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

    [题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...

  6. 【CodeForces】913 D. Too Easy Problems

    [题目]D. Too Easy Problems [题意]给定n个问题和总时限T,每个问题给定时间ti和限制ai,当解决的问题数k<=ai时问题有效,求在时限T内选择一些问题解决的最大有效问题数 ...

  7. AtcoderGrandContest 005 F. Many Easy Problems

    $ >AtcoderGrandContest \space 005 F.  Many Easy Problems<$ 题目大意 : 有一棵大小为 \(n\) 的树,对于每一个 \(k \i ...

  8. 【AGC005F】Many Easy Problems (NTT)

    Description ​ 给你一棵\(~n~\)个点的树和一个整数\(~k~\).设为\(~S~\)为树上某些点的集合,定义\(~f(S)~\)为最小的包含\(~S~\)的联通子图的大小.\(~n~ ...

  9. 【AGC005F】Many Easy Problems FFT 容斥原理

    题目大意 给你一棵树,有\(n\)个点.还给你了一个整数\(k\). 设\(S\)为树上某些点的集合,定义\(f(S)\)为最小的包含\(S\)的联通子图的大小. \(n\)个点选\(k\)个点一共有 ...

随机推荐

  1. Mybatis入门教程之新增、更新、删除功能_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 上一节说了Mybatis的框架搭建和简单查询,这次我们来说一说用Mybatis进行基本的增删改操作: 一. 插入一条数据 ...

  2. scanf() 与 gets()--转载

    scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别.若想从键盘上输入字符串"hi hello",则应该使用__gets__函数. gets可以接收空格:而 ...

  3. 前端HTTP缓存

    Web 缓存大致可以分为:数据库缓存.服务器端缓存(代理服务器缓存.CDN 缓存).浏览器缓存.其中前端比较关心的是浏览器缓存,包括今天要说的HTTP缓存和前面说过的cookie.localStora ...

  4. JavaSE知识点:finalize,treeMap

    *)finalize finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. *)treeMap 参考 ...

  5. oracle各服务说明及cmd启动启动命令

    成功安装Oracle 11g后,共有7个服务,一.这七个服务的含义分别为:1. Oracle ORCL VSS Writer Service:Oracle卷映射拷贝写入服务,VSS(Volume Sh ...

  6. 启用和配置 FILESTREAM

    2017/08/23 在开始使用 FILESTREAM 之前,必须在 SQL Server 数据库引擎实例中启用 FILESTREAM. 本主题说明了如何使用 SQL Server 配置管理器来启用 ...

  7. vim推荐的光标移动配置文件?

    http://roclinux.cn/?p=1466 inoremap jk inoremap ... 参考较好的vim设置文件 : 共享粘贴板: set clipboard+=unnamed 除了映 ...

  8. Vue实战:音乐播放器(一) 页面效果

    先看一下效果图 首页 歌单详情页 歌手列表 歌手详情页 排行页面 榜单的详情页(排序样式) 搜索页面 搜索结果 播放器内核 歌词自动滚动 播放列表 用户中心

  9. pom.xml文件设置

    一个相对完整的maven配置文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...

  10. Openstack_SQLAlchemy_一对多关系表的多表插入实现

    目录 目录 Openstack 与 SQLAlchemy 一个多表插入的 Demo 小结 Openstack 与 SQLAlchemy SQLAlchemy 是 Python 语言下的一款开源软件,它 ...