【题解】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])\)。我们拿个同记录相同的组合数的上面的那个数,这个数组设为\(s_i\)那么设答案为\(a_k\),有(\(b_0=0\))
\[ a_k=\sum_{i=0}^n b_i{i\choose k} \]
拆开
\[ a_k=\sum_{i=0} {b_i i!\over k! (i-k)!} \]
随便化一下
\[ k!a_k=\sum_{i} {(b_ii!)\over (i-k)!} \]
按照上次的那种套路搞出来就能NTT了
这一发TLE了,不知道为什么......
upd: AtCoder 编译命令没有-DONLINE_JUDGE
//@winlere
#include
#include
#include
#include
#include
using namespace std; typedef long long ll;
inline int qr(){
int ret=0,f=0,c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1<<19|1;
const int mod=924844033;
typedef vector poly;
poly buk(maxn),c(maxn),ans;
int inv[maxn],siz[maxn],r[maxn],jc[maxn],n;
inline int MOD(const int&x){return x-mod>=0?x-mod:x;}
inline int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
inline int MOD(const vector&ve){int ret=1;for(const auto&t:ve) ret=MOD(ret,t); return ret;}
inline int ksm(const int&ba,const int&p){
int ret=1;
for(int t=p,b=ba;t;t>>=1,b=MOD(b,b))
if(t&1) ret=MOD(ret,b);
return ret;
}
const int g=5;
const int gi=ksm(5,mod-2);
void pre(const int&n){
jc[0]=inv[0]=1;
for(int t=1;t<=n;++t) jc[t]=MOD(jc[t-1],t);
inv[n]=ksm(jc[n],mod-2);
for(int t=n-1;t;--t) inv[t]=MOD(inv[t+1],t+1);
}
void NTT(poly&a,const int&tag){
static int r[maxn];
int len=a.size();
for(int t=1;t>1]>>1|(t&1?len>>1:0))>t)
swap(a[t],a[r[t]]);
for(int t=1,wn,s=tag==1?g:gi;t=0) ++buk[n-siz[now]];
}
int main(){
n=qr();
buk.resize(n+1);
c.resize(n+1);
for(int t=1;t