题面

两道题比较像,放在一起写了,后者可以看成前者的加强版

(sto ztb orz)


先看AT那道题

考虑计算每个点的贡献,用容斥计算:每个点没有贡献当且仅当选的所有点都在以他为根时的一个子节点的子树里。所以对于每个点i,其贡献为$C_n^k-\sum_{v∈son_i}C_{size[v]}^k$,这样我们就得到了一个$O(n^2)$的算法

考虑优化,来列出来总的式子

$ans=n*C_n^k-\sum\limits_{i=1}^n\sum_{v∈son_i}C_{size[v]}^k$

前面的随便算,先不管了。考虑后面,用卷积优化时常见的套路,开个桶$bkt[i]$统计size等于i的情况的个数

$ans'=\sum\limits_{i=1}^n bkt[i] C_{i}^k$

组合数,拆除!

$ans'=\sum\limits_{i=1}^n bkt[i]*i! \frac{1}{k!(i-k)!}$

$k!*ans'=\sum\limits_{i=1}^n bkt[i]*i! \frac{1}{(i-k)!}$

上NTT即可


再来看ER那道题

我们仍然考虑贡献,点i产生贡献有两种方式:

1.作为被选出的点,有$C_{n-1}^{k-1}$种选的方法

2.作为构建虚树时被捉出来的LCA

显然重点在第二种上,我们仍然使用容斥来计算......

额式子太长了,不想写了,搬题解了

来啊,NTT啊(


Code:

Many Easy Problems↓

 #include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,mod=;
int n,nm,t1,t2,cnt,G,Gi;
int p[N],noww[N],goal[N],siz[N];
int rev[N],fac[N],inv[N],a[N],b[N],pw[][];
void Read(int &x)
{
x=; char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
x=(x<<)+(x<<)+(ch^),ch=getchar();
}
int Addit(int x,int y)
{
x+=y;
if(x>=mod) x-=mod;
return x;
}
int Qpow(int x,int k)
{
if(k==) return x;
int tmp=Qpow(x,k/);
return k%?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
}
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
noww[++cnt]=p[t];
goal[cnt]=f,p[t]=cnt;
}
int C(int a,int b)
{
return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
}
void DFS(int nde,int fth)
{
siz[nde]=;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde);
a[siz[goal[i]]]++;
siz[nde]+=siz[goal[i]];
}
a[n-siz[nde]]++;
}
void Pre()
{
fac[]=inv[]=;
for(int i=;i<=n;i++) fac[i]=1ll*fac[i-]*i%mod;
inv[n]=Qpow(fac[n],mod-);
for(int i=n-;i;i--) inv[i]=1ll*inv[i+]*(i+)%mod;
nm=*n,n=; while(n<=nm) n<<=; G=,Gi=Qpow(G,mod-),nm>>=;
for(int i=;i<=n;i++) rev[i]=(rev[i>>]>>)+(i&)*(n>>);
for(int i=;i<=;i++)
{
pw[i][]=Qpow(G,(mod-)/(<<i));
pw[i][]=Qpow(Gi,(mod-)/(<<i));
}
for(int i=;i<=nm;i++) a[i]=1ll*a[i]*fac[i]%mod,b[i]=inv[nm-i];
}
void Trans(int *arr,int len,int typ)
{
register int i,j,k;
for(i=;i<len;i++)
if(rev[i]>i) swap(arr[rev[i]],arr[i]);
for(i=;i<=len;i<<=)
{
int lth=i>>,ort=pw[(int)log2(i)][typ==-];
for(j=;j<len;j+=i)
{
int ori=,tmp;
for(k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
{
tmp=1ll*ori*arr[k+lth]%mod;
arr[k+lth]=(arr[k]-tmp+mod)%mod;
arr[k]=(arr[k]+tmp)%mod;
}
}
}
if(typ==-)
{
int Ni=Qpow(len,mod-);
for(i=;i<=len;i++)
arr[i]=1ll*arr[i]*Ni%mod;
}
}
int main()
{
Read(n);
for(int i=;i<n;i++)
Read(t1),Read(t2),Link(t1,t2);
DFS(,),Pre();
Trans(a,n,),Trans(b,n,);
for(int i=;i<n;i++) a[i]=1ll*a[i]*b[i]%mod;
Trans(a,n,-);
for(int i=;i<=nm;i++)
{
int ans=1ll*C(nm,i)*nm%mod-1ll*a[nm+i]*inv[i]%mod;
printf("%d\n",Addit(ans,mod));
}
return ;
}

两开花↓

 #include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,mod=;
int n,m,nm,t1,t2,cnt,G,Gi;
int p[N],noww[N],goal[N],siz[N];
int rev[N],fac[N],inv[N],a[N],b[N],pw[][];
void Read(int &x)
{
x=; char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
x=(x<<)+(x<<)+(ch^),ch=getchar();
}
int Addit(int x,int y)
{
x+=y;
if(x>=mod) x-=mod;
return x;
}
int Qpow(int x,int k)
{
if(k==) return x;
int tmp=Qpow(x,k/);
return k%?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
}
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
noww[++cnt]=p[t];
goal[cnt]=f,p[t]=cnt;
}
int C(int a,int b)
{
return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
}
void DFS(int nde,int fth)
{
siz[nde]=;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde);
siz[nde]+=siz[goal[i]];
}
a[n-]++; int tmp=;
for(int i=p[nde];i;tmp++,i=noww[i])
if(goal[i]!=fth) a[n-siz[nde]+siz[goal[i]]]--;
a[n-siz[nde]]+=tmp--(nde!=);
}
void Pre()
{
fac[]=inv[]=;
for(int i=;i<=n;i++) fac[i]=1ll*fac[i-]*i%mod;
inv[n]=Qpow(fac[n],mod-);
for(int i=n-;i;i--) inv[i]=1ll*inv[i+]*(i+)%mod;
nm=*n,n=; while(n<=nm) n<<=; G=,Gi=Qpow(G,mod-),nm>>=;
for(int i=;i<=n;i++) rev[i]=(rev[i>>]>>)+(i&)*(n>>);
for(int i=;i<=;i++)
{
pw[i][]=Qpow(G,(mod-)/(<<i));
pw[i][]=Qpow(Gi,(mod-)/(<<i));
}
for(int i=;i<=nm;i++) a[i]=1ll*Addit(a[i],mod)*fac[i]%mod,b[i]=inv[nm-i];
}
void Trans(int *arr,int len,int typ)
{
register int i,j,k;
for(i=;i<len;i++)
if(rev[i]>i) swap(arr[rev[i]],arr[i]);
for(i=;i<=len;i<<=)
{
int lth=i>>,ort=pw[(int)log2(i)][typ==-];
for(j=;j<len;j+=i)
{
int ori=,tmp;
for(k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
{
tmp=1ll*ori*arr[k+lth]%mod;
arr[k+lth]=(arr[k]-tmp+mod)%mod;
arr[k]=(arr[k]+tmp)%mod;
}
}
}
if(typ==-)
{
int Ni=Qpow(len,mod-);
for(i=;i<=len;i++)
arr[i]=1ll*arr[i]*Ni%mod;
}
}
int main()
{
Read(n),Read(m);
for(int i=;i<n;i++)
Read(t1),Read(t2),Link(t1,t2);
DFS(,),Pre();
Trans(a,n,),Trans(b,n,);
for(int i=;i<n;i++) a[i]=1ll*a[i]*b[i]%mod;
Trans(a,n,-);
for(int i=;i<=m;i++)
{
int ans=Addit(1ll*a[nm+i]*inv[i]%mod,1ll*C(nm-,i-)*nm%mod);
printf("%lld\n",1ll*ans*Qpow(C(nm,i),mod-)%mod);
}
return ;
}

解题:AT2064 Many Easy Problems&EXNR #1 T3 两开花的更多相关文章

  1. AtcoderGrandContest 005 F. Many Easy Problems

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

  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. [AT2064] [agc005_f] Many Easy Problems

    题目链接 AtCoder:https://agc005.contest.atcoder.jp/tasks/agc005_f 洛谷:https://www.luogu.org/problemnew/sh ...

  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. 总结 : C#事件理解

    要理解事件,首先必须理解委托!! 1.如果说委托是一个类型,那么事件就是一个对象! 2.事件的创建必须是借助某个委托类型来完成的! 3.也就是说,委托是事件的类型,事件本身是个对象!! 4.所以,事件 ...

  2. 基于RapidJSON的操作库

    需要安装配置RapidJSON库 /******************************************************************* * summery: 提供便 ...

  3. 如何完全卸载VS2010(亲自体验过) (转)

    1.首先用360卸载,当卸载完成后,提示有残余的话,就强力清除 2,接着,下载IobitUninstaller工具 3.按照下面进行卸载 1.Microsoft .NET Framework 4 框架 ...

  4. shell变量常用方法

    变量之数组操作: 参考网址:http://www.jb51.net/article/55253.htm #直接赋值 [root@local-]=chengd [root@local-]=xrd [ro ...

  5. service手动实例化(new)导致类中的spring对象无法注入的问题解决

    下面说的这个画横线的可能是错误的,因为我之前用controller继承父类的注解对象的时候成功了,所以可能这次的唯一原因就是 不该把本该从ioc容器中拿出的对象通过new的方式实例化,至于继承注解对象 ...

  6. 【Direct2D1.1初探】Direct2D特效概览

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Direct2D是一个基于Direct3D的2D图形API,可以利用硬件加速特性来提供高性能高质量的2D渲染.但 ...

  7. 简单测评拨号VPS——云立方&淘宝卖家

    做爬虫的同学不可避免地要使用代理IP,除了各网站公布的免费代理IP外,我们还可以选择拨号VPS,本文简单对两家(类)拨号VPS提供商进行测评,如有差错,欢迎指出,非常感谢. 使用过程 云立方 第一次听 ...

  8. Intellij IDEA 文件修改提示星号

    https://www.cnblogs.com/zheting/p/7594073.html

  9. SCRUM 12.09 软件工程第二周计划

    第二轮迭代的第二周开始了,上一周我们进行了对代码优化的探索与自我审查. 本周,我们有以下两点目标要实现: 1.对客户端进行优化. 2.网络爬虫爬取美团外卖. 客户端优化主要开发人员:高雅智.牛强.彭林 ...

  10. 对软件工程Alpha迭代的反思与总结

    对软件工程Alpha迭代的反思与总结 本次软件工程的A轮迭代,我们组出了不小的问题.作为一个团队来说,我们的队伍出现了很严重的状况,严重到让老师觉得我们一度失控.于是我撰写此文,借以反思.总结和提高. ...