题目大意

  给你一棵树,有\(n\)个点。还给你了一个整数\(k\)。

  设\(S\)为树上某些点的集合,定义\(f(S)\)为最小的包含\(S\)的联通子图的大小。

  \(n\)个点选\(k\)个点一共有\(\binom{n}{k}\)中方案,请你求出所有方案的\(f(S)\)的和\(\mod 924844033\)。

  出题人觉得这样就太简单了,他决定让你求出所有\(k=1\ldots n\)的答案。

  \(n\leq 200000\)

题解

  似乎对于每个\(k\)没办法快速求出答案。

  我们考虑一个点对所有答案的贡献。

  一个点\(x\)在这个联通子图内当且经当这\(k\)个点不在以\(x\)为根时\(x\)的子树内。

  那么贡献为\(\binom{n}{k}-\sum \binom{a_i}{k}\),其中\(a_i\)为以\(x\)为根时各个子树的大小。可以发现,计算总的贡献时每条边两端的子树大小都会被计算一次。\(\binom{n}{k}\)会被计算\(n\)次。

  设
\[ b_i= \begin{cases} n~~~~~~~~~~(i=n)\\ num_i~~~(i\neq n) \end{cases} \]
其中\(num_i\)为大小为\(i\)的子树的个数
\[ \begin{align} ans_k&=\sum_{i\geq k} b_i\binom{i}{k}\\ &=\sum_{i\geq k} b_i\frac{i!}{(i-k)!k!}\\ &=\frac 1{k!}\sum_{i\geq k}b_ii!\times \frac{1}{(i-k)!} \end{align} \]
  这可以转化成卷积的形式
\[ \begin{align} c_{n-i}&=num_ii!\\ d_{i}&=\frac{1}{i!}\\ a_i&=\sum_{j+k=i}c_id_i\\ ans_i&=\frac{a_{n-i}}{i!} \end{align} \]
  时间复杂度:\(O(n\log n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<list>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll p=924844033;
const ll g=5;
ll fp(ll a,ll b)
{ll s=1;while(b){if(b&1)s=s*a%p;a=a*a%p;b>>=1;}return s;
}
namespace ntt
{ll w1[1000010];ll w2[1000010];int rev[1000010];int n;void init(){
#ifdef DEBUGn=16;
#elsen=524288;
#endifint i;for(i=1;i<=n;i<<=1){w1[i]=fp(g,(p-1)/i);w2[i]=fp(w1[i],p-2);}rev[0]=0;for(i=1;i<n;i++)rev[i]=(rev[i>>1]>>1)|(i&1?n>>1:0);}void ntt(ll *a,int t){int i,j,k;ll u,v,w,wn;for(i=0;i<n;i++)if(rev[i]<i)swap(a[i],a[rev[i]]);for(i=2;i<=n;i<<=1){wn=(t==1?w1[i]:w2[i]);for(j=0;j<n;j+=i){w=1;for(k=j;k<j+i/2;k++){u=a[k];v=a[k+i/2]*w%p;a[k]=(u+v)%p;a[k+i/2]=(u-v)%p;w=w*wn%p;}}}if(t==-1){ll inv=fp(n,p-2);for(i=0;i<n;i++)a[i]=a[i]*inv%p;}}
};
ll b[1000010];
ll c[1000010];
ll a[1000010];
ll inv[1000010];
ll fac[1000010];
ll ifac[1000010];
int s[1000010];
int n;
list<int> l[200010];
ll num[1000010];
void dfs(int x,int fa)
{s[x]=1;for(auto v:l[x])if(v!=fa){dfs(v,x);s[x]+=s[v];num[s[v]]--;num[n-s[v]]--;}
}
int main()
{
#ifdef DEBUGfreopen("b.in","r",stdin);freopen("b.out","w",stdout);
#endifscanf("%d",&n);int i,x,y;for(i=1;i<=n-1;i++){scanf("%d%d",&x,&y);l[x].push_back(y);l[y].push_back(x);}inv[0]=inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;for(i=2;i<=n;i++){inv[i]=-(p/i)*inv[p%i]%p;fac[i]=fac[i-1]*i%p;ifac[i]=ifac[i-1]*inv[i]%p;}dfs(1,0);num[n]=n;for(i=0;i<=n;i++)b[i]=num[n-i]*fac[n-i]%p;for(i=0;i<=n;i++)c[i]=ifac[i];ntt::init();ntt::ntt(b,1);ntt::ntt(c,1);for(i=0;i<ntt::n;i++)a[i]=b[i]*c[i]%p;ntt::ntt(a,-1);for(i=1;i<=n;i++){ll ans=a[n-i]*ifac[i]%p;ans=(ans+p)%p;printf("%lld\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/ywwyww/p/8513285.html

【AGC005F】Many Easy Problems FFT 容斥原理相关推荐

  1. 【bzoj3771】Triple FFT+容斥原理

    题目描述 樵夫的每一把斧头都有一个价值,不同斧头的价值不同.总损失就是丢掉的斧头价值和. 他想对于每个可能的总损失,计算有几种可能的方案. 注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视 ...

  2. AtcoderGrandContest 005 F. Many Easy Problems

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

  3. [CF923D]Too Easy Problems

    Too Easy Problems 题解 看到这东西,我们明显可以把每个字母的变化先理一理. 于是,我们便得到了:与 接下来我们要将一个序列变为另一个序列. 我们发现,一个序列的后缀的A是不能够凭空产 ...

  4. 【AGC005F】Many Easy Problems (NTT)

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

  5. 解题报告(二)C、(darkBZOJ 3771)Triple(生成函数 + FFT + 容斥原理)(3)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  6. BZOJ3771 Triple(FFT+容斥原理)

    思路比较直观.设A(x)=Σxai.先把只选一种的统计进去.然后考虑选两种,这个直接A(x)自己卷起来就好了,要去掉选同一种的情况然后除以2.现在得到了选两种的每种权值的方案数,再把这个卷上A(x). ...

  7. AT2064-[AGC005F]Many Easy Problems【NTT】

    正题 题目链接:https://www.luogu.com.cn/problem/AT2064 题目大意 给出nnn个点的一棵树,对于k∈[1,n]k\in[1,n]k∈[1,n]求出所有kkk个点的 ...

  8. Notebook for Integer Programming (Laurence A. Wolsey) - Well-Solved Problems

    整数规划中的 Well-Solved Problems 文章目录 整数规划中的 Well-Solved Problems 摘要 Properties of Easy Problems 几类Well-S ...

  9. 对于人工智能的学习有哪些建议?【转】

    转自:https://www.zhihu.com/question/20132531 张石 咳咳,农民伯伯来了,我家那片代码有点荒了呀 人工智能编程--咳咳,我也是搬运工.... AI Program ...

最新文章

  1. 程序员的创业陷阱:接私活
  2. 如何查看ddos 放开的ip
  3. Oacle 开窗函数 分析函数
  4. javascript测试_了解有关JavaScript承诺的更多信息:25次测试中从零到英雄
  5. 工人与资本家互相养活,主动权在资本家手里
  6. 使用百度统计分析你的网站访问数据
  7. 党建活动献爱心,达飞云贷冬日送温暖
  8. 中国股市:史上最新A股龙头股票
  9. Bugly-全量更新
  10. JDK下载应该选择哪个版本?教你选择最好的JDK版本
  11. 关于图像模式识别的几种分类方法概述
  12. 测试功能点----方法
  13. 让你的桌面腾飞吧(OpenSolaris2008.05 + VirtualBox + WinXP)
  14. IBM JDK的Java堆空间的碎片问题
  15. c语言写一个会动的爱心图片,一键生成心形bmp图片
  16. ENVI BSQ转BIL或者BIP
  17. excel文件底层xml分析,如何实现高效解析excel
  18. 顶尖文案app_topys顶尖文案app下载
  19. matlab-colormap使用
  20. 中国中心城市和都市圈发展指数发布:成都天津位次紧跟北上深广,合肥提升最明显,大连下跌幅度较大...

热门文章

  1. mysql中的day(0_MySQL代码执行0-day漏洞 可本地提权
  2. python hadoop_让python在hadoop上跑起来
  3. android 删除特定字符串,android-从改造响应中删除不需要的字符串
  4. controller层个人信息查询模块_风险控制平台架构+模块
  5. 小学计算机知识题,小学信息技术基础知识试题
  6. linux程序安装包怎么用,制作Linux下程序安装包——使用脚本打包bin、run等安装包...
  7. python dtype o_python – 为什么dtype = str的空数据框填充“n”?
  8. 移动端常见bug汇总001
  9. [Erlang 0022] It solves the right problems in the right way at the right time
  10. 深度学习框架中的魔鬼:探究人工智能系统中的安全问题