College geeks Challenge CUP preliminary round second field C. different world purfer sequence + Stirling numbers of second kind of fantasy

The meaning of problems: n represents a given number of points, the sum of n nodes constituting ask all reference numerals have unrooted tree leaf nodes.

 

First of all the "numbers have rootless tree" to describe a strong hint about the sequence and purfer, each with a different purfer sequences uniquely represent constitute a tree, and this sequence is equal to the contribution of the answer sequence of numbers did not appear in the number.

Then we can go to find each appeared exactly k number of program sequences of color, that is, we can see that this program is exactly the number C (n, k) * T (n, k) * k! T is the second category number Stirling, Stirling numbers of second kind nlogn we need to find a way to NTT convolution can find a board to seek.

 

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=4e5+10;
const LL P=998244353,yg=3;
LL n,fac[N],inv[N],f[N],g[N],S2[N];
LL bin[N];

LL power(LL x,LL p) {
    LL ret=1;
    for (;p;p>>=1) {
        if (p&1) ret=(ret*x)%P;
        x=(x*x)%P;
    }
    return ret;
}

void NTT(LL *a,LL n,LL op) {  //NTT:系数a数组,长度为n,op=1求值op=-1插值 
    for(LL i=0;i<n;i++) bin[i]=(bin[i>>1]>>1)|((i&1)*(n>>1));
    for(LL i=0;i<n;i++) if(i<bin[i]) swap(a[i],a[bin[i]]);
    for(LL i=1;i<n;i<<=1) {
        LL wn=power(yg,op==1?(P-1)/(2*i):(P-1)-(P-1)/(2*i)),w,t;
        for(LL j=0;j<n;j+=i<<1) {
            w=1;
            for(LL k=0;k<i;k++) {
                t=a[i+j+k]*w%P;w=w*wn%P;
                a[i+j+k]=(a[j+k]-t+P)%P;a[j+k]=(a[j+k]+t)%P;
            }
        }
    }
    if(op==-1) {
        LL Inv=power(n,P-2);
        for(LL i=0;i<n;i++) a[i]=a[i]*Inv%P;
    }
}
long long C(long long n,long long m){return fac[n]*inv[m]%P*inv[n-m]%P;}
int main()
{
    cin>>n;
    if(n==1)
    {
        printf("1\n");
        return 0;
    }
    if(n==2)
    {
        printf("2\n");
        return 0;
    }
    fac[0]=inv[0]=1;
    for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P,inv[i]=power(fac[i],P-2);
    for (int i=0;i<=n;i++) f[i]=(power(-1,i)+P)%P*inv[i]%P;
    for (int i=0;i<=n;i++) g[i]=power(i,n-2)*inv[i]%P;
    
    LL N=n-1;
    LL len=1;while(len<(n+1)<<1) len<<=1;
    
    NTT(f,len,1); NTT(g,len,1);
    for (int i=0;i<len;i++) S2[i]=(f[i]*g[i])%P;  //求f.g的卷积为S2 
    NTT(S2,len,-1);
    
    long long ans=0;
    for(int i=1;i<=n-2;i++)
    {
        long long d=fac[i]*S2[i];
        d%=P;
        //printf("%d %lld %lld\n",n-i,d,S2[i]);
        ans+=d*C(n,i)%P*(n-i)%P;
        ans%=P;
    } 
    Years % = P = P + years, years =% P; 
    printf ( " % lld \ n " , year);
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/megalovania/p/11222009.html
Recommended