2018SD省队集训R2 D3

T1

这里写图片描述

题解

首先我们写一个dfs然后打出表来,上oeis找规律。。。
找到一个

i = 0 a S t i r l i n g 2 ( a + 1 , i + 1 ) ( 1 ) a i i n a i !

把第二类斯特林数的求法带进去
i = 0 a ( 1 ) a i i ! i n a k = 0 i + 1 ( 1 ) k k ! ( i + 1 k ) a + 1 ( i + 1 k ) !

这样化完之后就是一个NTT的题目了

代码

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
const int N=300005;
const int mod=998244353;
LL a[N],b[N],ans,mul[N],inv[N],invmul[N];int r[N],n,fn,A;
LL ksm(LL a,LL k)
{
    LL ans=1;
    for (;k;k>>=1,a=a*a%mod)
      if (k&1) ans=ans*a%mod;
    return ans;
}
void NTT(LL *a,int id)
{
    for (int i=0;i<n;i++)
      if (i<r[i]) swap(a[i],a[r[i]]);
    for (int k=1;k<n;k<<=1)
    {
        LL wn=ksm(3,(mod-1)/(k<<1));
        for (int i=0;i<n;i+=(k<<1))
        {
            LL w=1;
            for (int j=0;j<k;j++,w=w*wn%mod)
            {
                LL x=a[i+j],y=w*a[i+j+k]%mod;
                a[i+j]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
            }
        }
    }
    if (id==-1) reverse(a+1,a+n);
}
void init()
{
    mul[0]=1;
    for (int i=1;i<=n;i++) mul[i]=mul[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    invmul[0]=1;
    for (int i=1;i<=n;i++) invmul[i]=invmul[i-1]*inv[i]%mod;
    a[0]=1;b[0]=0;
    for (int i=1;i<=A+1;i++) 
    {
        a[i]=invmul[i];if (i&1) a[i]=-a[i];
        b[i]=invmul[i]*ksm(i,A+1)%mod;
    }
}
int main()
{
    freopen("per.in","r",stdin);
    freopen("per.out","w",stdout);
    scanf("%d%d",&fn,&A);
    int L=0;
    for (n=1;n<=(A+1)*2;n<<=1) L++;
    for (int i=0;i<n;i++) r[i]=(r[i>>1]>>1) | ((i&1)<<L-1);
    init();
    NTT(a,1); NTT(b,1);
    for (int i=0;i<n;i++) a[i]=a[i]*b[i]%mod;
    NTT(a,-1);
    for (int i=0;i<=A;i++) 
    {
        LL t=mul[i]*ksm(i,fn-A)%mod*a[i+1]%mod*inv[n]%mod;
        if ((A-i)&1) t=-t;
        ans=(ans+t+mod)%mod;
    }
    printf("%lld",(ans+mod)%mod);
}

T2

这里写图片描述

题解

subtask1就是暴力拆解。
subtask2的操作是(x+1)^nm,是二项式定理, c k = C n k 表示x^k的系数,那么从1开始递推可以求

代码

44pts(因为本人代码丑借用dalao代码QAQ

if (n<=2&&m<=2)
    {
        if (n>m) swap(n,m),swap(a,b);
        if (n==2)
        {
            LL a1a2=a[2],b1b2=b[2],ahe=a[1],bhe=b[1];
            h[0]=1; h[1]=ahe*bhe%mod;
            h[2]=(a1a2*bhe%mod*bhe%mod+b1b2*ahe%mod*ahe%mod)%mod;
            h[2]=(h[2]-2ll*a1a2%mod*b1b2%mod+mod)%mod;
            h[3]=a1a2*b1b2%mod*ahe%mod*bhe%mod;
            h[4]=a1a2*a1a2%mod*b1b2%mod*b1b2%mod;
            for (int i=0;i<k;i++) printf("%d ",h[i]);
        }
        else
        {
            h[0]=1; h[1]=1ll*a[1]*b[1]%mod;
            h[2]=a[1]*a[1]%mod*b[2]%mod;
            for (int i=0;i<k;i++) printf("%d ",h[i]);
        }
        return 0;
    }
    LL now=1,nm=n*m%mod,down=1;
    for (int i=0;i<k;i++)
    {
        printf("%lld ",now);
        now=now*nm%mod;
        now=now*ksm(down,mod-2)%mod;
        nm--; down++;
    }

猜你喜欢

转载自blog.csdn.net/blue_cuso4/article/details/80902844
D3
今日推荐