[题解] Atcoder AGC 005 F Many Easy Problems NTT,组合数学
题目
观察当k固定时答案是什么。先假设每个节点对答案的贡献都是\(\binom{n}{k}\),然后再减掉某个点没有贡献的选点方案数。对于一个节点i,它没有贡献的方案数显然就是所有k个节点都选在i连出去的某一个子树内的方案数。枚举节点i,把i连出去的每一个子树的size都加入一个序列c,则答案为\(\binom{n}{k}\cdot n-\sum_{i=0}^{|c|-1}\binom{c_i}{k}\)。
考虑\(k=1\cdots n\)的情况:
\(ans_k=\binom{n}{k}\cdot n-\sum_{i=0}^{|c|-1}\binom{c_i}{k}=\binom{n}{k}\cdot n-\sum_{i=0}^{|c|-1}\binom{c_i}{c_i-k}=\binom{n}{k}\cdot n-\sum_{i=0}^{|c|-1}\frac{c_i!}{k!(c_i-k)!}\)
\(-ans_k k!+\binom nk\cdot n\cdot k!=\sum_{i=0}^{|c|-1}\frac{c_i!}{(c_i-k)!}\)
统计每种\(c_i\)的出现次数后,右边就变成了一个减法卷积的形式,一遍NTT即可。需要注意题目中的模数的原根是5.时间复杂度\(O(nlogn)\)。
点击查看代码
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <LL,LL>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
using namespace std;
const LL MOD=924844033;
LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if((a&1)==1) ret=ret*res%MOD;
a>>=1;
res=res*res%MOD;
}
return ret;
}
namespace poly
{
vector <LL> rev;
void ntt(vector <LL> &a,LL G)
{
LL nn=a.size(),gn,g,x,y;vector <LL> tmp=a;
rep(i,nn) a[i]=tmp[rev[i]];
for(int len=1;len<nn;len<<=1)
{
gn=qpow(G,(MOD-1)/(len<<1));
for(int i=0;i<nn;i+=(len<<1))
{
g=1;
for(int j=i;j<i+len;++j,(g*=gn)%=MOD)
{
x=a[j];y=a[j+len]*g%MOD;
a[j]=(x+y)%MOD;a[j+len]=(x-y+MOD)%MOD;
}
}
}
}
vector <LL> convolution(vector <LL> a,vector <LL> b,LL G)
{
LL nn=1,bt=0,sv=a.size()+b.size()-1;while(nn<a.size()+b.size()-1) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(b.size()<nn) b.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
ntt(a,G);ntt(b,G);
rep(i,nn) (a[i]*=b[i])%=MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
vector <LL> inverse(vector <LL> a,LL G)
{
if(a.size()==1) return vector <LL>{qpow(a[0],MOD-2)};
vector <LL> aa=a;while(aa.size()>(a.size()+1)>>1) aa.pop_back();
vector <LL> bb=inverse(aa,G);
LL nn=1,bt=0,sv=a.size();while(nn<a.size()*2) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(bb.size()<nn) bb.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
ntt(a,G);ntt(bb,G);
rep(i,nn) a[i]=(2LL-a[i]*bb[i]%MOD+MOD)*bb[i]%MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
vector <LL> sqrt1(vector <LL> a,LL G)//常数项为1
{
if(a.size()==1) return vector <LL>{1};
vector <LL> aa=a;while(aa.size()>(a.size()+1)>>1) aa.pop_back();
vector <LL> bb=sqrt1(aa,G);while(bb.size()<a.size()) bb.pb(0);
vector <LL> bbb=inverse(bb,G);
LL nn=1,bt=0,sv=a.size();while(nn<a.size()*2) nn<<=1LL,++bt;
while(a.size()<nn) a.pb(0);while(bb.size()<nn) bb.pb(0);while(bbb.size()<nn) bbb.pb(0);
rev.clear();
rep(i,nn)
{
rev.pb(0);
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bt-1));
}
LL mul=qpow(2,MOD-2);
ntt(a,G);ntt(bb,G);ntt(bbb,G);
rep(i,nn) a[i]=mul*(bb[i]+bbb[i]*a[i]%MOD)%MOD;
ntt(a,qpow(G,MOD-2));
while(a.size()>sv) a.pop_back();
LL inv=qpow(nn,MOD-2);
rep(i,a.size()) (a[i]*=inv)%=MOD;
return a;
}
}
LL n,sz[200010],fac[200010],inv[200010],ans[200010];
vector <LL> g[200010],A,B,C;
LL CC(LL nn,LL mm){return fac[nn]*inv[mm]%MOD*inv[nn-mm]%MOD;}
void dfs(LL pos,LL par)
{
sz[pos]=1;
rep(i,g[pos].size()) if(g[pos][i]!=par)
{
dfs(g[pos][i],pos);
sz[pos]+=sz[g[pos][i]];
++A[sz[g[pos][i]]];
}
if(pos!=1) ++A[n-sz[pos]];
}
int main()
{
fac[0]=1;repn(i,200005) fac[i]=fac[i-1]*(LL)i%MOD;
rep(i,200003) inv[i]=qpow(fac[i],MOD-2);
cin>>n;
LL x,y;
rep(i,n-1)
{
scanf("%lld%lld",&x,&y);
g[x].pb(y);g[y].pb(x);
}
rep(i,n) A.pb(0);
dfs(1,0);
rep(i,n) (A[i]*=fac[i])%=MOD;
rep(i,n) B.pb(inv[i]);
reverse(B.begin(),B.end());
C=poly::convolution(A,B,5);
repn(i,n)
{
ans[i]=CC(n,i)*n%MOD;
(ans[i]+=MOD-(i+n-1>=C.size() ? 0LL:C[i+n-1])*inv[i]%MOD)%=MOD;
}
repn(i,n) printf("%lld\n",ans[i]);
return 0;
}
[题解] Atcoder AGC 005 F Many Easy Problems NTT,组合数学的更多相关文章
- AtcoderGrandContest 005 F. Many Easy Problems
$ >AtcoderGrandContest \space 005 F. Many Easy Problems<$ 题目大意 : 有一棵大小为 \(n\) 的树,对于每一个 \(k \i ...
- 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT
[题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...
- 【AGC 005F】Many Easy Problems
Description One day, Takahashi was given the following problem from Aoki: You are given a tree with ...
- AtCoder Grand Contest 005F - Many Easy Problems
$n \leq 200000$的树,从树上选$k$个点的一个方案会对$Ans_k$产生大小为“最小的包括这$k$个点的连通块大小”的贡献.求每个$Ans_k$.膜924844033. 看每个点对$An ...
- 【AGC005F】Many Easy Problems (NTT)
Description 给你一棵\(~n~\)个点的树和一个整数\(~k~\).设为\(~S~\)为树上某些点的集合,定义\(~f(S)~\)为最小的包含\(~S~\)的联通子图的大小.\(~n~ ...
- 【AtCoder】AGC005F - Many Easy Problems
题解 我们把一个点的贡献转化为一条边的贡献,因为边的数量是点的数量-1,最后再加上选点方案数\(\binom{n}{k}\)即可 一条边的贡献是\(\binom{n}{k} - \binom{a}{k ...
- 解题:AT2064 Many Easy Problems&EXNR #1 T3 两开花
题面 两道题比较像,放在一起写了,后者可以看成前者的加强版 (sto ztb orz) 先看AT那道题 考虑计算每个点的贡献,用容斥计算:每个点没有贡献当且仅当选的所有点都在以他为根时的一个子节点的子 ...
- 【CodeForces】913 D. Too Easy Problems
[题目]D. Too Easy Problems [题意]给定n个问题和总时限T,每个问题给定时间ti和限制ai,当解决的问题数k<=ai时问题有效,求在时限T内选择一些问题解决的最大有效问题数 ...
- [atcoder contest 010] F - Tree Game
[atcoder contest 010] F - Tree Game Time limit : 2sec / Memory limit : 256MB Score : 1600 points Pro ...
随机推荐
- 基于infiniband(IB)网的MVAPICH2安装
一.下载安装包 下载链接:http://mvapich.cse.ohio-state.edu/downloads/ 二.解压编译安装 mkdir /home/xujb/mvapich2 tar -x ...
- JAVA基础-11-Java Number 类--九五小庞
问题:一直有疑惑,为什么java中学习了基本数据类型,而不使用,使用的是封装的对象. 解答: 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等. ...
- 四位一体水溶交融,Docker一拖三Tornado6.2 + Nginx + Supervisord非阻塞负载均衡容器式部署实践
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_203 容器,又见容器.Docker容器的最主要优点就在于它们是可移植的.一套服务,其所有的依赖关系可以捆绑到一个独立于Linux内 ...
- Odoo14 自定义widget小部件
不多说先上源码. 1 odoo.define('my_company_users_widget', function (require) { 2 "use strict"; 3 4 ...
- 手把手教你定位线上MySQL锁超时问题,包教包会
昨晚我正在床上睡得着着的,突然来了一条短信. 什么?线上的订单无法取消! 我赶紧登录线上系统,查看业务日志. 发现有MySQL锁超时的错误日志. 不用想,肯定有另一个事务正在修改这条订单,持有这条订单 ...
- 自己做一个RTOS
什么是操作系统?其实就是一个程序, 这个程序可以控制计算机的所有资源,对资源进行分配,包括CPU时间,内存,IO端口等,按一定规则分配给所需要的进程(进程?也就是一个程序,可以单独执行),并且自动控制 ...
- Luogu2251 质量检测 (ST表)
我怎么开始划水了... #include <iostream> #include <cstdio> #include <cstring> #include < ...
- 如何开发一款基于 Vite+Vue3 的在线表格系统(上)
今天,葡萄带你了解如何基于Vite+Vue3实现一套纯前端在线表格系统. 在正式开始项目介绍之前,首先咱们首先来介绍一下Vite和Vue3. Vue3 Vue是什么?大多前端开发者对这个词已毫不陌生了 ...
- 痞子衡嵌入式:浅析IAR下调试信息输出机制之硬件UART外设
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR下调试信息输出机制之硬件UART外设. 在嵌入式世界里,输出打印信息是一种非常常用的辅助调试手段,借助打印信息,我们可以比较容易地 ...
- html + css 实现无需 js 的打字效果
以前要达到类似在电脑上打字的效果,需要 js+html.今天我将介绍一种新方法.本文主要介绍纯 html+css 实现打字效果,有一定的参考价值,大家可以学习一下.提供所有代码,可以直接使用. 一.原 ...