【AGC 005F】Many Easy Problems
Description
One day, Takahashi was given the following problem from Aoki:
You are given a tree with N vertices and an integer K. The vertices are numbered 1 through N. The edges are represented by pairs of integers (ai,bi).
For a set S of vertices in the tree, let f(S) be the minimum number of the vertices in a subtree of the given tree that contains all vertices in S.
There are C(n,k) ways to choose K vertices from the trees. For each of them, let S be the set of the chosen vertices, and find the sum of f(S) over all C(n,k) ways.
Since the answer may be extremely large, print it modulo 924844033(prime).
Since it was too easy for him, he decided to solve this problem for all K=1,2...N.
2≤N≤200000,1≤ai,bi≤N.The given graph is a tree.
Input
Output
Print N lines. The i-th line should contain the answer to the problem where K=i, modulo 924844033.
题意:给定一棵 $n$ 个节点的树,选出 $k$ 个特殊点,假设点集为 $S$,令 $f(S)$ 为最小的包含这 $k$ 个节点的连通块,分别求出 $k=1...n$ 在所有情况下的 $f(S)$ 的和。
分析:
考虑暴力,一个点被统计在连通块内,即在以它为根时,选出来的 $k$ 个点都在它的同一个儿子的子树内。即节点 $x$ 被统计进答案的次数 $g(x)$ 为:
$$g(x)=\binom{n}{k}-\sum _{(x,i)\subseteq E}\binom{sz_{i}}{k}$$
令 $cnt_{x}$ 表示上述公式里有多少个 $sz_{i}=x$,那么可以得到:
$$ans_{k}=\sum _{i=1}^{n}cnt_{i}\cdot\binom{i}{k}$$
整理可得:
$$k!\cdot ans_{k}=\sum _{i=1}^{n}\frac{cnt_{i}\cdot i!}{(i-k)!}$$
令 $a_{i}=cnt_{i}\cdot i!$,$b_{i}=(n-i)!$,则可得:
$$k!\cdot ans_{k}=\sum _{i=1}^{n}a_{i}\cdot b_{n-i+k}$$
最终答案为 $n\cdot \binom{n}{k}-ans_{k}$ 。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const int N=2e5+;
const int M=+;
const int mod=;
int n,nn,cnt,u,v,ans,first[N],fac[N],inv[N];
int num[N],sz[N],a[M],b[M];
struct edge{int to,next;}e[N*];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
void dfs(int x,int fa)
{
sz[x]=;
for(int i=first[x];i;i=e[i].next)
{
int to=e[i].to;
if(to==fa)continue;
dfs(to,x);
sz[x]+=sz[to];
}
if(fa!=-)a[sz[x]]++,a[n-sz[x]]++;
}
int power(int a,int b)
{
int ans=;
while(b)
{
if(b&)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;b>>=;
}
return ans;
}
void ntt(int *a,int n,int f)
{
int k=;while((<<k)<n)k++;
for(int i=;i<n;i++)
{
int t=;
for(int j=;j<k;j++)
if(i&(<<j))t|=(<<(k-j-));
if(i<t)swap(a[i],a[t]);
}
for(int l=;l<=n;l<<=)
{
int m=l>>,nw=power(,(mod-)/l);
if(f==-)nw=power(nw,mod-);
for(int *p=a;p!=a+n;p+=l)
{
int w=;
for(int i=;i<m;i++)
{
int t=1ll*p[m+i]*w%mod;
p[m+i]=(p[i]-t+mod)%mod;
p[i]=(p[i]+t)%mod;
w=1ll*w*nw%mod;
}
}
}
if(f==-)
{
int inv=power(n,mod-);
for(int i=;i<n;i++)a[i]=1ll*a[i]*inv%mod;
}
}
int main()
{
n=read();
for(int i=;i<n;i++)
{
u=read();v=read();
ins(u,v);ins(v,u);
}
dfs(,-);
fac[]=;
for(int i=;i<=n;i++)fac[i]=1ll*fac[i-]*i%mod;
inv[n]=power(fac[n],mod-);
for(int i=n;i>=;i--)inv[i-]=1ll*inv[i]*i%mod;
for(int i=;i<=n;i++)a[i]=1ll*a[i]*fac[i]%mod;
for(int i=;i<=n;i++)b[n-i]=inv[i];
nn=;while(nn<n+n+)nn<<=;
ntt(a,nn,);ntt(b,nn,);
for(int i=;i<nn;i++)a[i]=1ll*a[i]*b[i]%mod;
ntt(a,nn,-);
for(int i=;i<=n;i++)
{
ans=1ll*fac[n]*inv[i]%mod*inv[n-i]%mod*n%mod;
printf("%lld\n",(ans-1ll*a[n+i]*inv[i]%mod+mod)%mod);
}
return ;
}
【AGC 005F】Many Easy Problems的更多相关文章
- 【AGC005 F】Many Easy Problems
神他吗一天考一道码农题两道 FFT(其实还是我推式子一窍不通) 题意 给你一棵 \(n\) 个点的树,再给你一个常数 \(k\). 设 \(S\) 为树上某些点的集合,定义 \(f(S)\) 为最小的 ...
- 【期望DP】BZOJ3450- Tyvj1952 Easy
---恢复内容开始--- [题目大意] 有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个comb就有a*a分,comb就是极大的连续o.求期望分数. [思路] 比之前的OS ...
- 【Hello 2018 D】Too Easy Problems
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 可以考虑把所有的题目按照ai排序. 然后顺序考虑最后做出来的题目个数和第i道题目的ai一样. 则1..i-1这些题目就没有用了. 值 ...
- 【AGC005F】Many Easy Problems FFT 容斥原理
题目大意 给你一棵树,有\(n\)个点.还给你了一个整数\(k\). 设\(S\)为树上某些点的集合,定义\(f(S)\)为最小的包含\(S\)的联通子图的大小. \(n\)个点选\(k\)个点一共有 ...
- 【AGC005F】Many Easy Problems (NTT)
Description 给你一棵\(~n~\)个点的树和一个整数\(~k~\).设为\(~S~\)为树上某些点的集合,定义\(~f(S)~\)为最小的包含\(~S~\)的联通子图的大小.\(~n~ ...
- 【AGC005F】Many Easy Problems
Description 题目链接 对于每个\(k\),统计任选\(k\)个点作为关键点的"最小生成树"的大小之和 Solution 正向想法是枚举或者计算大小为\(x\).叶子数目 ...
- 【POJ 2826】An Easy Problem?!(几何、线段)
两个木条装雨水能装多少. 两线段相交,且不遮盖的情况下才可能装到水. 求出交点,再取两线段的较高端点的较小值h,(h-交点的y)为三角形的高. 三角形的宽即为(h带入两条线段所在直线得到的横坐标的差值 ...
- 【AGC 002F】Leftmost Ball
Description Snuke loves colorful balls. He has a total of N*K balls, K in each of his favorite N col ...
- 【hdu6334】【2018Multi-University-Training Contest04】Problem C. Problems on a Tree
维护1边的联通块和2边的联通块,合并的时候直接启发式合并. cdqz的大爷好强啊. #include<bits/stdc++.h> #define lson (o<<1) #d ...
随机推荐
- mysql表与表之间数据的转移
1.相同表结构 INSERT INTO table1 SELECT * FROM table2; 2.不同表结构 INSERT INTO table1(filed1,...,filedn) SELEC ...
- c编译器字节对齐指令
#pragma pack (n) 作用:C编译器将按照n个字节对齐.#pragma pack () 作用:取消自定义字节对齐方式. #pragma ...
- golang 调用windows API 中文的处理
Go语言发展势头很猛,其实缺点也很多,好在有广大爱好者提供了无数的库,把优点表现得太好了,搞得什么都是拿来就使用,基本完全不理会指针,性能还不错. 最近在windows下使用遇到一个中文的问题,首先要 ...
- ubunru18.04下面安装docker
sudo apt-get updat // 更新apt包索引 sudo apt-get remove docker docker-engine docker-ce docker.io // 卸载旧版本 ...
- timers模块
timers模块 var timers = require('timers'); function A() { //将A对象注册到定时器里 timers.enroll(); //进行激活,如果不激活, ...
- Django 使用mysql 创建项目
一.安装 mysql 和 mysqlclient 1. 安装 mysql ,https://www.jianshu.com/p/07a9826898c0 2. pip3 install mysqlcl ...
- Cordova入门系列(一)创建项目 转发 https://www.cnblogs.com/lishuxue/p/6008678.html
版权声明:本文为博主原创文章,转载请注明出处 Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的 ...
- vue 追书神器
app.vue页面 初始化数据,通过调用vuex mutation里定义的方法 调用保存到localstorage中的书架信息.搜索历史记录.字体大小和皮肤 并把这些数据保存的vuex state中 ...
- jeecg入门操作—树型表单开发
树表类型表单 表单创建,基础配置如下: 1.设置表单类型为:单表; 2.是否树选择:是; 3.设置特殊字段:[树形表单父id][树开表单列] 结果测试
- 新增和修改页面的用例设计和Bug提交
问题: 新增页面和修改页面,基本上输入框都一样,那比如同一个输入框的用例设计: 1. 写了新增页面的用例,修改页面对该输入框还有再写一遍用例的必要吗? 2. 执行用例时,新增页面验证了必填项,长度,数 ...