AGC005F - Many Easy Problems

题目描述

给定一棵树,设 $f_k$ 表示任选 $k$ 个点组成的最小连通块之和,求 $f(i),i \in [1,n]$

数据范围

$n \le 2 \times 10^5$

题解

考虑容斥,即一个点对于 $k$ 不会产生贡献的方案数

于是对于一个点 $u$ ,设其为根,它对 $k$ 的贡献可以列出式子: $(_k^n)-\sum_{v \in son_u}(_k^{size_v})$

于是 $f_k=n(_k^n)-\sum_{i=1}^ng_i(_k^{i})$ ,其中 $g_i$ 表示子树大小为 $i$ 的贡献

于是就可以 $Ntt$ 了,本题中的原根是 $5$ 。效率: $O(nlogn)$

代码

#include <bits/stdc++.h>
using namespace std;
const int N=8e5+5,P=924844033;
int n,hd[N],V[N],nx[N],t,p,A[N],G[2]={5,554906420},B[N],sz[N],r[N],jc[N],ny[N];
int X(int x){return x>=P?x-P:x;}
int K(int x,int y){
    int z=1;
    for (;y;y>>=1,x=1ll*x*x%P)
        if (y&1) z=1ll*z*x%P;
    return z;
}
void add(int u,int v){
    nx[++t]=hd[u];V[hd[u]=t]=v;
}
void dfs(int u,int fr){
    sz[u]=1;
    for (int i=hd[u];i;i=nx[i])
        if (V[i]!=fr){
            dfs(V[i],u);
            sz[u]+=sz[V[i]];
            A[sz[V[i]]]--;
        }
    if (u!=1) A[n-sz[u]]--;
}
void Ntt(int *a,int o){
    for (int i=0;i<t;i++)
        if (i<r[i]) swap(a[i],a[r[i]]);
    for (int wn,i=1;i<t;i<<=1){
        wn=K(G[o],(P-1)/(i<<1));
        for (int x,y,j=0;j<t;j+=(i<<1))
            for (int k=0,w=1;k<i;k++,w=1ll*w*wn%P)
                x=a[j+k],y=1ll*a[i+j+k]*w%P,
                a[j+k]=X(x+y),a[i+j+k]=X(x-y+P);
    }
    if (o)
        for (int i=0,v=K(t,P-2);i<t;i++)
            a[i]=1ll*a[i]*v%P;
}
int main(){
    cin>>n;jc[0]=1;
    for (int i=1,x,y;i<n;i++)
        scanf("%d%d",&x,&y),
        add(x,y),add(y,x);
    A[n]=n;dfs(1,0);
    for (int i=1;i<=n;i++)
        jc[i]=1ll*i*jc[i-1]%P;
    ny[n]=K(jc[n],P-2);
    for (int i=n;i;i--)
        ny[i-1]=1ll*i*ny[i]%P;
    for (int i=0;i<=n;i++)
        B[i]=ny[i],A[i]=1ll*X(A[i]+P)*jc[i]%P;
    reverse(B,B+n+1);
    for (t=1;t<n+n+2;t<<=1,p++);
    for (int i=0;i<t;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));
    Ntt(A,0);Ntt(B,0);
    for (int i=0;i<t;i++) A[i]=1ll*A[i]*B[i]%P;
    Ntt(A,1);
    for (int i=1;i<=n;i++) printf("%lld\n",1ll*ny[i]*A[n+i]%P);
    return 0;
}

原文地址:https://www.cnblogs.com/xjqxjq/p/12243164.html

时间: 2024-11-03 02:58:03

AGC005F - Many Easy Problems的相关文章

[题解] [AGC005F] Many Easy Problems

题面 题解 学长讲课题目的质量果然和我平常找的那些不一样 思路还是可以说比较巧妙的 考虑到我们并不好算出对于所有大小为 \(i\) 的点集,能够包含它的最小连通块大小 转换题目 这个时候我们应该想到把目标放到单个点 \(i\) 对选择 \(k\) 个点时的贡献 那么他的贡献就是总方案数减去没选的方案数对吧 没选的方案怎么算呢 记 \(sz[i]\) 为以 \(i\) 为根的子树的点数 分析发现, 当 \(k\) 个点同时在以它的儿子为根的一棵子树内就不会计算 \(i\) 这里的儿子的意义是, 以

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

[题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模924844033.n<=2*10^5. [算法]排列组合+NTT [题解]考虑每个点只会在k个点都在其一个子树时无贡献,即: $$ANS_k=\sum_{x=1}^{n}\binom{n}{k}-\sum_{y}\binom{sz[y]}{k}+\binom{n-sz[y]}{k}$$ 令$cnt_i$表示满足s

【题解】AT2064 Many Easy Problems(转换+NTT)

[题解]AT2064 Many Easy Problems(转换+NTT) 给定一棵树,请你回答\(k\in[1,n]\)由\(k\)个点生成出来的虚树(steiner)的所有方案的大小的和. 对于这种分元素然后每个元素对答案有一个相同的贡献的计数,一般都是考虑对于一个点考虑对于答案的贡献.对于一个确定的\(k\)和一个点\(p\),可以很轻易的算出\(p\)对于答案的贡献=\({n\choose k }-( \sum_{u \in Son}siz[u])-(n-siz[p])\).我们拿个同记

Codeforces B. Too Easy Problems

题目描述: time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are preparing for an exam on scheduling theory. The exam will last for exactly T milliseconds and will consist of n problems. You

[AGC005]:F - Many Easy Problem

F - Many Easy Problems Time limit : 5sec / Memory limit : 512MB Score : 1900 points Problem Statement 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 thr

重新写的Gridland

这道题是我很久以前的时候写的,今天我同学问我这道题怎么做,本想偷懒来着,直接看看,但是,没有任何的线索告诉我从那个角度出发,哎,这也是我不足的地方,下面先给题目,分析在后面. Background For years, computer scientists have been trying to find efficient solutions to different computing problems. For some of them efficient algorithms are

uva 10057 A mid-summer night’s dream(中位数)

uva 10057 A mid-summer night's dream This is year 2200AD. Science has progressed a lot in two hundred years. Two hundred years is mentioned here because this problem is being sent back to 2000AD with the help of time machine. Now it is possible to es

Two Wrongs Can Make a Right (and Are Difficult to Fix)

Two Wrongs Can Make a Right (and Are Difficult to Fix) Allan Kelly CODE NEVER LIES, BUT IT CAN CONTRADICT ITSELF. Some contradictions lead to those "How can that possibly work?" moments. In an interview,* the principal designer of the Apollo 11

《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题

这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就是一本题解书,简单暴力的通过题目的堆叠来提升解决编程问题的能力. 那么下面开始探索吧. zoj1037: BackgroundFor years, computer scientists have been trying to find efficient solutions to different computing p