1. 程式人生 > >AGC005F Many Easy Problems

AGC005F Many Easy Problems

題目

你有一棵無根樹(n個結點,1~n標號),和一個整數k。
對於一個樹上的結點集合S,可以用一個子樹把S中的點全部包含,這裡子樹指的是原樹結點的一個子集,並且這些結點全部連通。對於集合S,令f(S)表示這樣的子樹最少所包含的結點數目。
共有C(n,k)種方法選出樹上的k個結點。對於其中每種方法,設選出的點集為S,你需要求出所有這樣的f(S)的總和。
答案可能很大,需要對924844033取模。 你需要對所有k=1~n都回答上述問題。

題解

考慮暴力怎麼做。
最直接的想法,就是考慮一個點對Ans[k]的貢獻。

Ans[k]=Σi=1n(kn)Σjson[i](ksiz[j])[i1](knsiz[i])
然後O(n2)就能拿到40分了。
考慮答案式子。
Ans[k]=nCnkg[k]

k!g[k]=Σikcnt[i]i!1(ik)!
其中,cnt[k]表示在原先的式子裡siz[k]出現的次數。
f(i)=cnt[i]i!h(i)=1i!
k!g[k]=Σikf(i)h(ik)

好像我看不出什麼。
於是我在草稿紙上畫了畫,將i看成ni
於是整個式子又變成了k!g[k]=Σikf(i)h(nki)
其中f(i)=f(ni)
然後這就是卷積的形式了。
由於924844033的原根是5,所以就可以直接用NTT

程式碼

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm> #include<cstdio> #define N 200010 #define M 525000 #define LL long long #define mo 924844033 #define P(a) putchar(a) #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; struct note{ int to,next; };note edge[N*2]; int tot,head[N]; LL i,j,k,l,n,m,ans; LL u,v,L,len; LL jc[N],ny[N],fa[N]; LL siz[N],f[N],h[N]; LL f1[M],f2[M]; LL w[M],_w[M],Rev[M]; LL Ans[N]; LL read(){ LL fh=1,rs=0;char ch; while((ch<'0'||ch>'9')&&(ch^'-'))ch=getchar(); if(ch=='-')fh=-1,ch=getchar(); while(ch>='0'&&ch<='9')rs=(rs<<3)+(rs<<1)+(ch^'0'),ch=getchar(); return fh*rs; } void write(LL x){ if(x>9)write(x/10); P(x%10+'0'); } void lb(int x,int y){ edge[++tot].to=y; edge[tot].next=head[x]; head[x]=tot; } LL ksm(LL x,LL y){ LL rs=1; for(;y;y>>=1,x=(x*x)%mo) if(y&1)rs=(rs*x)%mo; return rs; } void pre_(){ int i; jc[0]=jc[1]=ny[0]=ny[1]=1; fo(i,2,N-10)jc[i]=(jc[i-1]*i)%mo; ny[N-10]=ksm(jc[N-10],mo-2); fd(i,N-11,2)ny[i]=(ny[i+1]*(i+1))%mo; } LL C(LL n,LL m){ if(n<m)return 0; return ((jc[n]*ny[m])%mo*ny[n-m])%mo; } void add(LL &x,LL y){ x=(x+y+mo)%mo; } void dg(int x){ int i; siz[x]=1; for(i=head[x];i;i=edge[i].next) if(fa[x]^edge[i].to){ fa[edge[i].to]=x; dg(edge[i].to); f[siz[edge[i].to]]++; siz[x]+=siz[edge[i].to]; } if(x^1)f[n-siz[x]]++; } void NTT(LL *y,LL *w){ LL i,h,k; fo(i,0,L-1) if(i<Rev[i]) swap(y[i],y[Rev[i]]); for(h=2;h<=L;h<<=1){ for(i=0;i<L;i+=h){ fo(k,i,i+(h>>1)-1){ LL u=y[k],t=(w[L/h*(k-i)]*y[k+(h>>1)])%mo; y[k]=(u+t)%mo; y[k+(h>>1)]=((u-t)%mo+mo)%mo; } } } } int main(){ n=read(); fo(i,1,n-1){ u=read();v=read(); lb(u,v);lb(v,u); } pre_(); dg(1); fo(i,1,n)f[i]=(f[i]*jc[i])%mo; fo(i,0,n)h[i]=ny[i]; len=0; for(L=1;L<(n+1)*2;L<<=1)len++; w[0]=w[L]=1; w[1]=ksm(5,(mo-1)/L); fo(i,1,L-1) w[i]=w[i-1]*1ll*w[1]%mo; fo(i,0,L) _w[i]=w[L-i]; fo(i,0,L-1)Rev[i]=Rev[i>>1]>>1|(i&1)<<len-1; fo(i,0,n)f1[i]=f[n-i]; fo(i,n+1,L-1)f1[i]=0; fo(i,0,n)f2[i]=h[i]; fo(i,n+1,L-1)f2[i]=0; NTT(f1,w); NTT(f2,w); fo(i,0,L-1)f1[i]=f1[i]*f2[i]%mo; NTT(f1,_w); LL inv=ksm(L,mo-2); fo(i,0,L-1)f1[i]=(f1[i]*inv)%mo; fo(i,1,n)Ans[i]=(f1[n-i]*ny[i])%mo; fo(i,1,n)Ans[i]=(n*C(n,i)%mo-Ans[i]+mo)%mo; fo(i,1,n)write(Ans[i]),P('\n'); return 0; }

相關推薦

AGC005F Many Easy Problems

題目 你有一棵無根樹(n個結點,1~n標號),和一個整數k。 對於一個樹上的結點集合S,可以用一個子樹把S中的點全部包含,這裡子樹指的是原樹結點的一個子集,並且這些結點全部連通。對於集合S,令f(S)表示這樣的子樹最少所包含的結點數目。 共有C(n,k)種

AGC005FMany Easy Problems-NTT

Description 連結 Solution 考慮每個點 u u u的貢獻對

[AGC005]:F - Many Easy Problem

orm reverse ould rac ins nim blog mat data- F - Many Easy Problems Time limit : 5sec / Memory limit : 512MB Score : 1900 points Pr

codeforces 913D Too Easy Problems

http://www.elijahqi.win/2018/01/09/codeforces-913d-too-easy-problems/ ‎ D. Too Easy Problems time limit per test 2 seconds memo

Codeforces Hello 2018 D. Too Easy Problems 二分+貪心

D. Too Easy Problems time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard out

Hello 2018 D. Too Easy Problems(貪心+優先佇列)

You are preparing for an exam on scheduling theory. The exam will last for exactly T milliseconds and will consist of n problems. You can either solve p

D. Too Easy Problems(二分,排序,貪心)

題目大意:給出n個問題和總時間t。給出的n個問題,對於每個問題都有一個限制題數,如果答題數超過了該題的限制題數,該題不得分;以及每道題所需要花費的時間。現在要求再規定時間內儘可能的拿高分。輸出結果不唯一,即順序不唯一,以及規定時間內做的不得分的題可算可不算。思路:二分,排序,

F - Many Moves

nts take abs bit cte from cst have form F - Many Moves Time limit : 2sec / Memory limit : 256MB Score : 900 points Problem State

How Many Boyfriends

2個 問題 最簡 期望 註意 12個 end 概率 化簡 知乎上看到一個問題,如果一個女人說自己集齊了12個星座的男朋友,那麽她已經搞過多少男人了。 先考慮這個問題的最簡單版本,如果說該女人每一次和12個星座的男人交往的概率相同。 考慮$dp$ 註意到這個問題正向十分不

Qt音樂播放器制作(二)Easy Player

滾動 支持 是個 blog 音樂 音樂播放器 div iss size 兩天沒有公布新的動態。主要原因還是個人的生活和工作時間限制,如今趕晚貼出第二版。先放個圖: 自上次公布第一個版本號以來,又進行了多次改動,主要變化在於: (1)依照上次的計劃又一次設計了界面

[ACM] POJ 3740 Easy Finding (DFS)

cas oss miss 矩陣 org fin contest std size Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16202 Accepted: 4349

Exception: Too many parameters were provided in this RPC request. The maximum

procedure protocol provided request stream Exception: Too many parameters were provided in this RPC request. The maximum is 2100. [Microsoft

測並發 Too many open files 問題的解決

ref get http sign pro light 程序 sched pen ulimit -a 查看限制顯示: core file size (blocks, -c) 0 data seg size (kbytes, -d) u

【POJ3740】Easy Finding DLX(Dancing Links)精確覆蓋問題

ren .cn string 應該 進行 int 函數 操作 urn 題意:多組數據。每組數據給你幾行數,要求選出當中幾行,使得每一列都有且僅有一個1,詢問是可不可行,或者說能不能找出來。 題解:1、暴搜。2、DLX(Dancing links)。 本文寫的是DLX。算

Easy sssp(spfa)

long long empty define lan true 超時 cnblogs space har vijos 1053 Easy sssp 方法:用spfa判斷是否存在負環 描述 輸入數據給出一個有N(2 <= N <= 1,000)個

How Many Tables HDU - 1213

tar line lan pro ica wan blank not example Today is Ignatius‘ birthday. He invites a lot of friends. Now it‘s dinner time. Ignatius wants

Leetcode--easy系列10

height per ive bsp weight itself val rtt sizeof #205 Isomorphic Strings Given two strings s and t, determine if they are isomorphic.

176. Second Highest Salary(Easy)

tco targe query rip con -s second count rom Source of the question Write a SQL query to get the second highest salary from the Employee t

595. Big Countries (Easy)

bsp pre and where eas country lee ont targe Source: https://leetcode.com/problems/big-countries/#/descriptionDescription: There is a tab

JavaSE 最easy出錯的幾個簡單的問題

成員 tde bsp ase log package 標識 多次 年齡 案例1. package cn.itcast.oop; public class ThisDemo { public static void main(String[] args) { S