题目链接

AtCoder:https://agc005.contest.atcoder.jp/tasks/agc005_f

洛谷:https://www.luogu.org/problemnew/show/AT2064

Solution

注意到模数为\(441\cdot 2^{21}+1\),嘿嘿

首先要想到考虑贡献,然后这题就简单了。

设当前要算的为\(f(i)\),我们考虑第\(x\)个点的贡献,显然可以得到贡献为:

\[\binom{n}{i}-\sum_{v\in son_{x}}\binom{sz_v}{i}
\]

就是所有的方案减去这个点选不到的方案,其中\(sz_v\)表示以\(x\)为根\(v\)的\(\rm size\)。

然后累和:

\[\begin{align}
f(i)&=\sum_{x=1}^{n}\left(\binom{n}{i}-\sum_{v\in son_{x}}\binom{sz_v}{i}\right)\\
&=n\binom{n}{i}-\sum_{x=1}^{n}\sum_{v\in son_x}\binom{sz_v}{i}
\end{align}
\]

后面那块不好处理,我们可以记个桶\(cnt(s)\)表示大小为\(s\)的子树出现了多少次,这个一遍\(\rm dfs\)就可以算出来。

那么把式子化一下:

\[\begin{align}
f(i)&=n\binom{n}{i}-\sum_{j=1}^{n}cnt(j)\binom{j}{i}\\
&=n\binom{n}{i}-\frac{1}{i!}\sum_{j=i}^{n}\frac{cnt(j)j!}{(j-i)!}
\end{align}
\]

注意到后面可以转化为卷积的形式,设:

\[g(i)=cnt(i)i!,h(i)=\frac{1}{i!}
\]

后面的\(\sum\)就是:

\[\sum_{j=i}^{n}g(j)h(j-i)=\sum_{j=0}^{n-i}g(j-i)h(j)
\]

我们\(\rm reverse\)一下\(g\):

\[\sum_{j=0}^{n-i}g_R((n-i)-j)h(j)
\]

\(NTT\)优化就好了,复杂度\(O(n\log n)\)。

注意这个神奇的模数原根是\(5\),我一开始写成\(3\)还以为是\(NTT\)挂了...

#include<bits/stdc++.h>
using namespace std; void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long
#define end puts("NO"),exit(0) const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 924844033; int add(int x,int y) {return x+y>mod?x+y-mod:x+y;}
int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;} int qpow(int a,int x) {
int res=1;
for(;x;x>>=1,a=mul(a,a)) if(x&1) res=mul(a,res);
return res;
} int fac[maxn],ifac[maxn],inv[maxn],pos[maxn],N,mxn,bit,n;
int w[maxn],rw[maxn],f[maxn],g[maxn],h[maxn],head[maxn],tot,sz[maxn];
struct edge{int to,nxt;}e[maxn<<1]; void ins(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;} void dfs(int x,int fa) {
sz[x]=1;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa) dfs(e[i].to,x),sz[x]+=sz[e[i].to],g[sz[e[i].to]]++;
g[n-sz[x]]++;
} void ntt_init() {
w[0]=rw[0]=1,w[1]=qpow(5,(mod-1)/mxn);
for(int i=2;i<=mxn;i++) w[i]=mul(w[i-1],w[1]);
rw[1]=qpow(w[1],mod-2);
for(int i=2;i<=mxn;i++) rw[i]=mul(rw[i-1],rw[1]);
} void ntt_get(int len) {
for(bit=0,N=1;N<=len;N<<=1,bit++);
for(int i=0;i<N;i++) pos[i]=pos[i>>1]>>1|((i&1)<<(bit-1));
} void ntt(int *r,int op) {
for(int i=1;i<N;i++) if(pos[i]>i) swap(r[i],r[pos[i]]);
for(int i=1,d=mxn>>1;i<N;i<<=1,d>>=1)
for(int j=0;j<N;j+=i<<1)
for(int k=0;k<i;k++) {
int x=r[j+k],y=mul((op==-1?rw:w)[k*d],r[i+j+k]);
r[j+k]=add(x,y),r[i+j+k]=del(x,y);
}
if(op==-1) {int d=qpow(N,mod-2);for(int i=0;i<N;i++) r[i]=mul(r[i],d);}
} int main() {
read(n);for(int x,y,i=1;i<n;i++) read(x),read(y),ins(x,y),ins(y,x);
dfs(1,0);fac[0]=ifac[0]=inv[0]=inv[1]=1;
for(int i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
for(int i=2;i<=n;i++) inv[i]=mul(mod-mod/i,inv[mod%i]);
for(int i=1;i<=n;i++) ifac[i]=mul(ifac[i-1],inv[i]);
for(int i=0;i<=n;i++) h[i]=ifac[i],g[i]=mul(g[i],fac[i]);
g[0]=0; reverse(g,g+n+1);for(mxn=1;mxn<=n<<1;mxn<<=1);
ntt_init(),ntt_get(n<<1),ntt(g,1),ntt(h,1);
for(int i=0;i<N;i++) f[i]=mul(g[i],h[i]);
ntt(f,-1);
for(int i=1;i<=n;i++) write(del(mul(n,mul(fac[n],mul(ifac[i],ifac[n-i]))),mul(ifac[i],f[n-i])));
return 0;
}

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

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

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

  2. Codeforces 913D - Too Easy Problems

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

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

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

  4. 【CodeForces】913 D. Too Easy Problems

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

  5. AtcoderGrandContest 005 F. Many Easy Problems

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

  6. Codeforces B. Too Easy Problems

    题目描述: time limit per test 2 seconds memory limit per test 256 megabytes input standard input output ...

  7. 【AGC 005F】Many Easy Problems

    Description One day, Takahashi was given the following problem from Aoki: You are given a tree with ...

  8. AtCoder - 2064 Many Easy Problems

    Problem Statement One day, Takahashi was given the following problem from Aoki: You are given a tree ...

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

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

随机推荐

  1. python基础——字符串

    Python的核心数据类型--字符串 常见字符串常量和表达式 操作 解释 s = '' 空字符串 s = "dodo's" 双引号和单引号 s = 'd\no\p\td\x00o' ...

  2. 基于ejabberd简单实现xmpp群聊离线消息

    首先,xmpp服务器是基于ejabberd.离线消息模块是mod_interact,原地址地址:https://github.com/adamvduke/mod_interact: 修改后实现群聊离线 ...

  3. 搜索引擎ElasticSearch系列(三): ElasticSearch2.4.4 bigdesk插件安装

    一:ElasticSearch bigdesk插件简介 bigdesk是elasticsearch的一个集群监控工具,可以通过它来查看es集群的各种状态,如:cpu.内存使用情况,索引数据.搜索情况, ...

  4. shell loop

    #!/bin/sh date i=0 while [ $i -le 30 ] do         echi $i /usr/sbin/r2/np_test_acl -f rule.txt i=$(e ...

  5. WebGL射线拾取模型——八叉树优化

    经过前面2篇WebGL射线拾取模型的文章,相信大家对射线和模型面片相交的原理已经有所了解,那么今天我们再深入探究关于射线拾取的一个问题,那就是遍历场景中的所有与射线相交的模型的优化问题.首先我们来复习 ...

  6. 如何选择 .NET Framework目标版本

    如何选择 .NET Framework目标版本 简介 .NET Framework是所有 .NET程序赖以运行的基础. 版本 到目前位置 .NET Framework共出了: .NET Framewo ...

  7. JavaScript学习笔记(五)——类型、转换、相等、字符串

    第六章 类型 相等 转换等 一.类型 1 typeof(); typeof是一个内置的JavaScript运算符,可用于探测其操作数的类型. 例: <script language=" ...

  8. leetcode26_C++删除排序数组中的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...

  9. 《Cocos2d-x游戏开发实战精解》学习笔记2--在Cocos2d-x中显示一行文字

    在Cocos2d-x中要显示文字就需要用到Label控件.在3.x版本的Cocos2d中,舍弃了之前版本所使用的LabelTTF.LabelAtlas.LabelBMFont 3个用于显示文字的类,而 ...

  10. mysql先删除后插入导致死锁

    所报的错误为:pymysql.err.OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting ...