解题:AT2064 Many Easy Problems&EXNR #1 T3 两开花

题面

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

(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↓

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=1600005,mod=924844033;
  8 int n,nm,t1,t2,cnt,G,Gi;
  9 int p[N],noww[N],goal[N],siz[N];
 10 int rev[N],fac[N],inv[N],a[N],b[N],pw[30][2];
 11 void Read(int &x)
 12 {
 13     x=0; char ch=getchar();
 14     while(!isdigit(ch))
 15         ch=getchar();
 16     while(isdigit(ch))
 17         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
 18 }
 19 int Addit(int x,int y)
 20 {
 21     x+=y;
 22     if(x>=mod) x-=mod;
 23     return x;
 24 }
 25 int Qpow(int x,int k)
 26 {
 27     if(k==1) return x;
 28     int tmp=Qpow(x,k/2);
 29     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
 30 }
 31 void Link(int f,int t)
 32 {
 33     noww[++cnt]=p[f];
 34     goal[cnt]=t,p[f]=cnt;
 35     noww[++cnt]=p[t];
 36     goal[cnt]=f,p[t]=cnt;
 37 }
 38 int C(int a,int b)
 39 {
 40     return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
 41 }
 42 void DFS(int nde,int fth)
 43 {
 44     siz[nde]=1;
 45     for(int i=p[nde];i;i=noww[i])
 46         if(goal[i]!=fth)
 47         {
 48             DFS(goal[i],nde);
 49             a[siz[goal[i]]]++;
 50             siz[nde]+=siz[goal[i]];
 51         }
 52     a[n-siz[nde]]++;
 53 }
 54 void Pre()
 55 {
 56     fac[0]=inv[0]=1;
 57     for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
 58     inv[n]=Qpow(fac[n],mod-2);
 59     for(int i=n-1;i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
 60     nm=2*n,n=1; while(n<=nm) n<<=1; G=5,Gi=Qpow(G,mod-2),nm>>=1;
 61     for(int i=1;i<=n;i++) rev[i]=(rev[i>>1]>>1)+(i&1)*(n>>1);
 62     for(int i=1;i<=24;i++)
 63     {
 64         pw[i][0]=Qpow(G,(mod-1)/(1<<i));
 65         pw[i][1]=Qpow(Gi,(mod-1)/(1<<i));
 66     }
 67     for(int i=0;i<=nm;i++) a[i]=1ll*a[i]*fac[i]%mod,b[i]=inv[nm-i];
 68 }
 69 void Trans(int *arr,int len,int typ)
 70 {
 71     register int i,j,k;
 72     for(i=0;i<len;i++)
 73         if(rev[i]>i) swap(arr[rev[i]],arr[i]);
 74     for(i=2;i<=len;i<<=1)
 75     {
 76         int lth=i>>1,ort=pw[(int)log2(i)][typ==-1];
 77         for(j=0;j<len;j+=i)
 78         {
 79             int ori=1,tmp;
 80             for(k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
 81             {
 82                 tmp=1ll*ori*arr[k+lth]%mod;
 83                 arr[k+lth]=(arr[k]-tmp+mod)%mod;
 84                 arr[k]=(arr[k]+tmp)%mod;
 85             }
 86         }
 87     }
 88     if(typ==-1)
 89     {
 90         int Ni=Qpow(len,mod-2);
 91         for(i=0;i<=len;i++)
 92             arr[i]=1ll*arr[i]*Ni%mod;
 93     }
 94 }
 95 int main()
 96 {
 97     Read(n);
 98     for(int i=1;i<n;i++)
 99         Read(t1),Read(t2),Link(t1,t2);
100     DFS(1,0),Pre();
101     Trans(a,n,1),Trans(b,n,1);
102     for(int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%mod;
103     Trans(a,n,-1);
104     for(int i=1;i<=nm;i++)
105     {
106         int ans=1ll*C(nm,i)*nm%mod-1ll*a[nm+i]*inv[i]%mod;
107         printf("%d\n",Addit(ans,mod));
108     }
109     return 0;
110 }
View Code

两开花↓

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=1600005,mod=998244353;
  8 int n,m,nm,t1,t2,cnt,G,Gi;
  9 int p[N],noww[N],goal[N],siz[N];
 10 int rev[N],fac[N],inv[N],a[N],b[N],pw[30][2];
 11 void Read(int &x)
 12 {
 13     x=0; char ch=getchar();
 14     while(!isdigit(ch))
 15         ch=getchar();
 16     while(isdigit(ch))
 17         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
 18 }
 19 int Addit(int x,int y)
 20 {
 21     x+=y;
 22     if(x>=mod) x-=mod;
 23     return x;
 24 }
 25 int Qpow(int x,int k)
 26 {
 27     if(k==1) return x;
 28     int tmp=Qpow(x,k/2);
 29     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
 30 }
 31 void Link(int f,int t)
 32 {
 33     noww[++cnt]=p[f];
 34     goal[cnt]=t,p[f]=cnt;
 35     noww[++cnt]=p[t];
 36     goal[cnt]=f,p[t]=cnt;
 37 }
 38 int C(int a,int b)
 39 {
 40     return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
 41 }
 42 void DFS(int nde,int fth)
 43 {
 44     siz[nde]=1;
 45     for(int i=p[nde];i;i=noww[i])
 46         if(goal[i]!=fth)
 47         {
 48             DFS(goal[i],nde);
 49             siz[nde]+=siz[goal[i]];
 50         }
 51     a[n-1]++; int tmp=0;
 52     for(int i=p[nde];i;tmp++,i=noww[i])
 53         if(goal[i]!=fth) a[n-siz[nde]+siz[goal[i]]]--;
 54     a[n-siz[nde]]+=tmp-1-(nde!=1);
 55 }
 56 void Pre()
 57 {
 58     fac[0]=inv[0]=1;
 59     for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
 60     inv[n]=Qpow(fac[n],mod-2);
 61     for(int i=n-1;i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
 62     nm=2*n,n=1; while(n<=nm) n<<=1; G=3,Gi=Qpow(G,mod-2),nm>>=1;
 63     for(int i=1;i<=n;i++) rev[i]=(rev[i>>1]>>1)+(i&1)*(n>>1);
 64     for(int i=1;i<=24;i++)
 65     {
 66         pw[i][0]=Qpow(G,(mod-1)/(1<<i));
 67         pw[i][1]=Qpow(Gi,(mod-1)/(1<<i));
 68     }
 69     for(int i=0;i<=nm;i++) a[i]=1ll*Addit(a[i],mod)*fac[i]%mod,b[i]=inv[nm-i];
 70 }
 71 void Trans(int *arr,int len,int typ)
 72 {
 73     register int i,j,k;
 74     for(i=0;i<len;i++)
 75         if(rev[i]>i) swap(arr[rev[i]],arr[i]);
 76     for(i=2;i<=len;i<<=1)
 77     {
 78         int lth=i>>1,ort=pw[(int)log2(i)][typ==-1];
 79         for(j=0;j<len;j+=i)
 80         {
 81             int ori=1,tmp;
 82             for(k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
 83             {
 84                 tmp=1ll*ori*arr[k+lth]%mod;
 85                 arr[k+lth]=(arr[k]-tmp+mod)%mod;
 86                 arr[k]=(arr[k]+tmp)%mod;
 87             }
 88         }
 89     }
 90     if(typ==-1)
 91     {
 92         int Ni=Qpow(len,mod-2);
 93         for(i=0;i<=len;i++)
 94             arr[i]=1ll*arr[i]*Ni%mod;
 95     }
 96 }
 97 int main()
 98 {
 99     Read(n),Read(m);
100     for(int i=1;i<n;i++)
101         Read(t1),Read(t2),Link(t1,t2);
102     DFS(1,0),Pre();
103     Trans(a,n,1),Trans(b,n,1);
104     for(int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%mod;
105     Trans(a,n,-1);
106     for(int i=1;i<=m;i++)
107     {
108         int ans=Addit(1ll*a[nm+i]*inv[i]%mod,1ll*C(nm-1,i-1)*nm%mod);
109         printf("%lld\n",1ll*ans*Qpow(C(nm,i),mod-2)%mod);
110     }
111     return 0;
112 }
View Code

 

posted @ 2019-02-25 21:59  Speranza_Leaf  阅读(216)  评论(0)    收藏  举报