记录编号 611351 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [THUPC 2025 Final] 对脑电波 最终得分 100
用户昵称 GravatarLikableP 是否通过 通过
代码语言 C++ 运行时间 205.473 s
提交时间 2026-01-28 13:07:28 内存使用 526.65 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
  int s=0,f=1;
  char c=getchar();
  while(c<'0'||c>'9')
  {
    if(c=='-')
    f=-1;
    c=getchar(); 
  }
  while(c>='0'&&c<='9')
  {
    s=s*10+c-'0';
    c=getchar();
  }
  return s*f;
}
int N,K,M,S; 
int a[5007];
long long ans=0;
const int mod=998244353;
int dp0[5007][5007],dp[5007][5007],dp2[5003][5003],g3[5003][5003];
long long jc[5003],ny[5003];
long long cf[5007][5007];
long long CC[5007][5007];
inline long long qpow(long long x,long long y)
{
  long long anss=1;
  while(y)
  {
    if(y&1)
    anss=anss*x%mod;
    x=x*x%mod;
    y>>=1;
  }
  return anss;
}
inline long long C(int n,int m)
{
  if(n<0||m<0||n<m)
  return 0;
  return CC[n][m];
}
struct INIT{
  inline void init()
  {
    for(int i=0;i<=5001;++i)
    {
      if(i==0)
      jc[i]=ny[i]=1;
      else
      jc[i]=jc[i-1]*i%mod,ny[i]=qpow(jc[i],mod-2);
      for(int j=0;j<=5001;++j)
      {
        cf[i][j]=qpow(i,j);
        if(j<=i)
        {
          if(j==0)
          CC[i][j]=1;
          else
          CC[i][j]=(CC[i-1][j-1]+CC[i-1][j])%mod;
        }
      }
    }
    dp0[0][0]=dp0[1][1]=1;
    dp[1][1]=1;
    for(int i=2;i<=N;++i)
    {
      for(int j=1;j<=i;++j)
      {
        dp0[i][j]=((long long)dp0[i-1][j-1]+(long long)dp0[i-1][j]*(i-1))%mod;
        dp[i][j]=dp0[i-1][j-1];
      }
    }
    
    for(int i=1;i<=N;++i)
      for(int j=2;j<=i;++j)
        dp2[i][j]=(dp2[i][j]+(long long)dp[i-1][j-1]*(i-1))%mod; 
    for(int i=1;i<=N;++i)
    {
      for(int j=1;j<=i;++j)
      {
        g3[i][j]=(g3[i][j]+(long long)dp0[i-1][j-1]*(i-1))%mod;
      }
    }
  }
}Init;
struct CASE1{
  long long ans=0;
  int b[5007];
  long long f[5007][5007];
  inline long long Solve()
  {
    int c1=S+1,c2=S+1; 
    for(int i=2;i<=S;++i)
    {
      if(a[i-1]<a[i])
      c1=min(c1,i);
      if(a[i-1]>a[i])
      c2=min(c2,i);
    }
    if(c2>c1)
    {
      for(int i=1;i<=S;++i)
      a[i]=M-a[i]+1;
      swap(c1,c2); 
    }
    int n=N-(S-c1+1),m=n,k=K-(S-c1+1);
    for(int i=1;i<c1;++i)
    {
      b[i]=a[i];
      for(int j=c1;j<=S;++j)
      {
        if(a[i]>a[j])
        --b[i];
      }
    }
    for(int i=1;i<=n;++i)
    f[c1-1][i]=C(b[c1-1]-1,i-1)*jc[i-1]%mod*i%mod;
    for(int j=c1-2;j>=1;--j)
      for(int i=1;i<=n;++i)
      {
        f[j][i]=f[j+1][i-1];
        if(b[j]-i+1>=0)
        f[j][i]=(f[j][i]+f[j][i-1]*(b[j]-i+1))%mod;
      }
    int i1=m-b[1]+1,j1=k-(c1-2);
    for(int nj2=c1-2;nj2<=k-1;++nj2)
    {
      int j2=k-nj2-1,i2=n-nj2-i1;
      long long anss=(long long)dp[i1][j1]*dp[i2+1][j2+1]%mod*C(i1-1+i2,i2)%mod;
      ans=(ans+anss*f[2][nj2])%mod;
    }
    for(int i=1;i<3;++i)
    {
      b[i]=a[i];
      for(int j=3;j<=S;++j)
      {
        if(a[i]>a[j])
        --b[i];
      }
    }
    n=N-(S-2);
    for(int nj1=1;nj1+S<=K;++nj1)
    {
      int j1=K-nj1-(S-1),i1=(n-b[1]+1)-nj1;
      int j2=K-S,i2=b[1]-2;
      long long anss=(long long)dp[i1][j1]*dp[i2+1][j2+1]%mod*C(i1-1+i2,i2)%mod;
      ans=(ans+anss*jc[nj1]%mod*C(n-b[1],nj1))%mod;
    }
    return ans;
  }
}Case1;
struct CASE2{
  long long ans=0;
  int b[5007],n,k,c;
  long long f[5007][5007];
  inline long long Solve()
  {
    ans=0;
    c=S+1;
    for(int i=2;i<=S;++i)
    {
      if(a[i]>a[i-1])
      {
        c=i;
        break;
      }
    }
    for(int i=1;i<c;++i)
    {
      b[i]=a[i];
      for(int j=c;j<=S;++j)
      {
        if(a[i]>a[j])
        --b[i];
      }
    }
    n=N-(S-c+1);
    k=K-(S-c+1);
    for(int i=0;i<=N;++i)
      for(int j=0;j<=N;++j)
        f[i][j]=0;
    for(int i=1;i<=n;++i)
    f[c-1][i]=C(b[c-1]-1,i-1)*jc[i-1]%mod*i%mod;
    for(int j=c-2;j>=1;--j)
      for(int i=1;i<=n;++i)
      {
        f[j][i]=f[j+1][i-1];
        if(b[j]-i+1>=0)
        f[j][i]=(f[j][i]+f[j][i-1]*(b[j]-i+1))%mod;
      }
    for(int i0=1;i0<=n;++i0)
    {
      long long anss=0;
      int i1=n-b[1];
      int j1=K-S;
      int ai2=b[1]-i0;
      for(int k2=2;k2<=ai2;++k2)
      {
        int i2,j2;
        i2=k2-1;
        j2=k-i0-1;
        anss=(anss+(long long)(k2-1)*dp[i1+1][j1+1]%mod*dp[i2][j2]%mod*C(i1+i2,i2)%mod*C(i1+i2+ai2-k2,ai2-k2)%mod*jc[ai2-k2]%mod)%mod;
      }
      for(int k2=1;k2<=i1;++k2)
      {
        int i2=ai2+k2-1;
        int j2=k-i0-1;
        anss=(anss+(long long)ai2*dp[i2][j2]%mod*dp0[i1-k2][j1]%mod*C(i2+i1-k2-1,i2)%mod)%mod;
      }
      ans=(ans+anss*f[1][i0])%mod;
    }
    for(int i0=1;i0<=n;++i0)
    {
      long long anss=0;
      int i1=n-b[1];
      int j1=K-S;
      int ai2=b[1]-i0;
      for(int k2=1;k2<=i1;++k2)
      {
        int i2=ai2+k2;
        int j2=k-i0;
        anss=(anss+(long long)dp[i2][j2]*dp0[i1-k2][j1]%mod*C(i2+i1-k2-1,i2)%mod)%mod;
      }
      if(c==2)
      ans=(ans+anss*C(b[1]-1,i0-1)%mod*jc[i0-1])%mod;
      else
      ans=(ans+anss*f[2][i0-1])%mod;
    }
    for(int i=1;i<=S;++i)
    a[i]=M-a[i]+1;
    return ans;
  }
}Case2;
struct CASE3{
  long long ans=0;
  int n,k,c;
  inline long long Solve()
  {
    n=N-S+1;
    k=K-S+1;
    ans=0;
    c=a[1];
    for(int i=1;i<=S;++i)
    {
      if(a[i]<a[1])
      --c;
    }
    for(int k1=1;k1<c;++k1)
    {
      for(int i0=1;i0<=n;++i0)
      {
        int i1=n-k1-1;
        int i2=n-2-i1-i0;
        int j2=K-S-i0;
        if(i2>=0&&j2>=0)
        ans=(ans+(long long)dp[i1+1][K-S]*g3[i2+1][j2+1]%mod*C(i1+1+i2,i1+1)%mod*C(k1-1,i0-1)%mod*jc[i0-1]%mod)%mod;
      }
    }
    for(int i=1;i<=S;++i)
    a[i]=M-a[i]+1;
    return ans;
  }
}Case3;
bool vis[100007];
int main()
{
  freopen("thupc_2025_BrainWave.in", "r", stdin);
  freopen("thupc_2025_BrainWave.out", "w", stdout);
  N=read(),K=read(),S=read();
  M=N;
  for(int i=1;i<=S;++i)
  {
    a[i]=read();
    if(vis[a[i]])
    {
      puts("0");
      return 0;
    }
    vis[a[i]]=1;
  }
  Init.init();
  ans=(ans+Case1.Solve())%mod;
  ans=(ans+Case2.Solve())%mod;
  ans=(ans+Case2.Solve())%mod;
  ans=(ans+Case3.Solve())%mod;
  ans=(ans+Case3.Solve())%mod;
  printf("%lld\n",ans);
  return 0;
}