在最少出一张攻击牌,尽量多的打强化牌,因为它至少让牌翻倍,排序选出最大攻击牌,强化牌不够,再打出较大攻击牌
设 (f_{i,j})为考虑了排序后的前 (i) 张强化牌且第 (i) 张必选,选了 (j) 张牌的效果,(g_{i,j})为考虑了排序后的前 (i) 张攻击牌且第 (i) 张必选,选了 (j) 张牌的效果,得:
[f[i][j]=v_isum_{k=j-1}^{i-1}f[k][j-1]\
g[i][j]={i-1choose j-1}v_i+sum_{k=j-1}^{i-1}g[k][j-1]
]
考虑(f,g)对(F,G)贡献
[F[i][j]=sum_{k=j}^n{n-kchoose i-j}f[k][j]\
G[i][j]=sum_{k=j}^n{n-kchoose i-j}g[k][j]
]
#include<cstdio>
#include<algorithm>
#define mod 998244353
using namespace std;
const int maxn = 3001;
inline int read() {
char c=std::getchar();int x=0;while(c<'0'||x>'9') c=std::getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=std::getchar();return x;
}
int c[maxn][maxn],dp[maxn][maxn],f[maxn][maxn];
int g[maxn][maxn],h[maxn][maxn];
int n,m,k;
int a[maxn],b[maxn];
bool cmp(int a,int b){return a > b;}
inline int C(int n,int m){return m > n ? 0 : c[n][m];}
int main(){
int T,M=2000;T = read();
for(int i = 0;i <= M;i++) c[i][0] = c[i][i] = 1;
for(int i = 1;i <= M;i++)
for(int j = 1;j < i;j++)
c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
while(T--){
n = read();m = read();k = read();
for(int i = 1;i <= n;i++) a[i] = read();
for(int i = 1;i <= n;i++) b[i] = read();
std::sort(a+1,a+n+1,cmp); std::sort(b+1,b+n+1,cmp);
dp[0][0] = 1;
for(int i=1;i<=n;i++)
for(int j=0;j<=i;j++) {
dp[i][j]=dp[i-1][j];
if(j) dp[i][j]=(dp[i][j]+1ll*dp[i-1][j-1]*a[i]%mod)%mod;
}
f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
f[i][j]=1ll*dp[i-1][j-1]*a[i]%mod;
h[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=i;j++) {
h[i][j]=h[i-1][j];
if(j) h[i][j]=(h[i][j]+1ll*C(i-1,j-1)*b[i]%mod+h[i-1][j-1])%mod;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
g[i][j]=(1ll*C(i-1,j-1)*b[i]%mod+h[i-1][j-1])%mod;
int ans=0;
for(int i=0;i<m;i++) {
int now=0;
for(int j=0;j<=n;j++) {
if(i<=k-1) now=(now+f[j][i])%mod;
else now=(now+1ll*f[j][k-1]*C(n-j,i-k+1)%mod)%mod;
}
int tot=0,res=0;
if(i<=k-1) res=k-i;else res=1;
for(int j=0;j<=n;j++)
tot=(tot+1ll*g[j][res]*C(n-j,m-i-res)%mod)%mod;
ans=(ans+1ll*now*tot%mod)%mod;
}
printf("%d
",ans);
}
}