bzoj5093 图的价值

我们对每个点单独考虑贡献,枚举其度数,别的点之间随便连

$$ans=n\cdot2^{C_{n-1}^{2}}\cdot\sum_{i=0}^{n-1}{ {C_{n-1}^{i}} \cdot {i^{k}}}$$

考虑$m^{n}$为将n个球放进m个盒子的方案数,于是我们枚举放到了几个盒子里,利用第二类斯特林数

$$m^{n}=\sum_{i=0}^{m}{{C_{m}^{i}} \cdot {S(n,i)} \cdot {i!}}$$

所以$$ans=n\cdot2^{C_{n-1}^{2}}\cdot\sum_{i=0}^{n-1}{ {C_{n-1}^{i}} \cdot {\sum_{j=0}^{i}{{C_{i}^{j}} \cdot {S(k,j)} \cdot {j!}}}}$$

$$ans=n\cdot2^{C_{n-1}^{2}}\cdot {\sum_{j=0}^{n-1}{  {S(k,j)} \cdot {j!}}}  \cdot  {\sum_{i=j}^{n-1}{  { C_{n-1}^{i} }\cdot {C_{i}^{j}} }}$$

又因为$$ {\sum_{i=j}^{n}{  { C_{n}^{i} }\cdot {C_{i}^{j}} }}={\sum_{i=j}^{n}{  { C_{n}^{j} }\cdot {C_{n-j}^{i-j}} }}=C_{n}^{j}  \cdot  {  \sum_{i=0}^{n}{C_{n-j}^{i}}  }=C_{n}^{j}*2^{n-j}$$

所以$$ans=n\cdot2^{C_{n-1}^{2}}\cdot {\sum_{j=0}^{n-1}{  {S(k,j)} \cdot {j!}}} \cdot C_{n-1}^{j}\cdot 2^{n-j-1}$$

这时候我们发现$j$的枚举上限可以降低到$k$,因为$S(k,j)=0(j>k)$

对于第二类斯特林数,我们发现$$S(n,m)={\frac{1}{m!}}    {\sum_{i=0}^{m}{{(-1)^{i}}   \cdot  {C_{m}^{i}}  \cdot   {(m-i)^{n}}  }}$$

$$={\sum_{i=0}^{m}{  {\frac{(-1)^{i}}{i!}}   \cdot  { \frac{(m-i)^{n}}{(m-i)!}}  }}$$

发现是卷积的形式,于是我们可以直接上NTT,于是复杂度就变成了$O({k}  \cdot  {log(k)})$

至此,我们完美的解决了这道题!

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #define MAXN 533333
 7 #define int long long
 8 #define mod 998244353
 9 using namespace std;
10 int A[MAXN],B[MAXN],S[MAXN];
11 int C[MAXN],rev[MAXN],n,N,K;
12 int NY,ny[MAXN],fac[MAXN],ans;
13 int qp(int a,int b){
14     int c=1;
15     while(b){
16         if(b&1)c=c*a%mod;
17         a=a*a%mod; b>>=1;
18     }return c;
19 }
20 void ntt(int *a,int o){
21     register int i,j,k,dan,now,t;
22     for(i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
23     for(k=2;k<=N;k<<=1){
24         dan=qp(3,o==1?(mod-1)/k:(mod-1-(mod-1)/k));
25         for(j=0;j<N;j+=k){
26             now=1;
27             for(i=0;i<(k>>1);i++,now=now*dan%mod){
28                 t=now*a[i+j+(k>>1)]%mod;
29                 a[i+j+(k>>1)]=(a[i+j]-t+mod)%mod;
30                 a[i+j]=(a[i+j]+t)%mod;
31             }
32         }
33     }
34     if(o==-1)for(i=0;i<N;i++)(a[i]*=NY)%=mod;
35 }
36 signed main(){
37     register int i;
38     scanf("%lld%lld",&n,&K);
39     fac[0]=ny[0]=1;
40     for(i=1;i<=K;i++){
41         fac[i]=fac[i-1]*i%mod;
42         ny[i]=qp(fac[i],mod-2);
43     }
44     C[0]=1;
45     for(i=1;i<=K;i++)
46         C[i]=C[i-1]*(n-i)%mod*qp(i,mod-2)%mod;
47     for(i=0;i<=K;i++){
48         A[i]=((i&1?-1:1)*ny[i]+mod)%mod;
49         B[i]=qp(i,K)*ny[i]%mod;
50     }
51     for(N=1;N<=K+K;N<<=1);
52     NY=qp(N,mod-2);
53     for(i=0;i<N;i++){
54         if(i&1)rev[i]=(rev[i>>1]>>1)|(N>>1);
55         else rev[i]=rev[i>>1]>>1;
56     }
57     ntt(A,1);ntt(B,1);
58     for(i=0;i<N;i++)S[i]=A[i]*B[i]%mod;
59     ntt(S,-1);
60     for(i=0;i<=min(n-1,K);i++)
61         (ans+=S[i]*fac[i]%mod*qp(2,n-i-1)%mod*C[i]%mod)%=mod;
62     ans=ans*n%mod*qp(2,((n-1)*(n-2)/2)%(mod-1))%mod;
63     printf("%lld\n",ans);
64     return 0;
65 }
View Code

 

posted @ 2018-02-27 17:26  Ren_Ivan  阅读(210)  评论(0编辑  收藏  举报