我们令$sum_i$表示数字i在加完数字的数列中出现的次数,那么答案显然为$\dfrac{(n+m)!}{\sum_{i=0}^{\infty}sum_i!}$

不难发现,当每次添加的数为$[l,r]$中出现次数最少的数时,答案就是最小的了。

然后就没了

貌似我常数比较大在loj上是997ms过的。。。。。。

 #include<bits/stdc++.h>
#define M 20000005
#define L long long
#define MOD 998244353
using namespace std;
const L INF=2e9; map<int,int> mp;
L num[M]={},nn=;
L n,m,l,r; L pow_mod(L x,L k){L ans=; for(;k;k>>=,x=x*x%MOD) if(k&) ans=ans*x%MOD; return ans;}
L fac[M]={}; L Main(){
nn=;
mp.clear();
scanf("%d%d%d%d",&n,&m,&l,&r);
L F=fac[n+m];
for(L i=;i<=n;i++){
L x; scanf("%d",&x);
mp[x]++;
}
L mul=;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
L x=it->first,y=it->second;
if(!(l<=x&&x<=r)) mul=mul*fac[y]%MOD;
else num[++nn]=y;
}
num[nn+]=;
sort(num+,num+nn+);
if(nn) reverse(num+,num+nn+);
L lr=r-l+; num[]=INF;
for(L i=nn;~i;i--){
L mns=1LL*(lr-i)*(num[i]-num[i+]);
if(mns<=m) {m-=mns; continue;}
L up=num[i+]+m/(lr-i);
L yu=m%(lr-i);
L mul2=pow_mod(fac[up+],yu);
L mul1=pow_mod(fac[up],lr-i-yu);
mul=mul*mul1%MOD*mul2%MOD;
for(int j=i;j>=;j--){
mul=mul*fac[num[j]]%MOD;
}
break;
}
mul=pow_mod(mul,MOD-);
cout<<F*mul%MOD<<endl;
} int main(){
fac[]=; for(L i=;i<M;i++) fac[i]=fac[i-]*i%MOD;
L cas; cin>>cas;
while(cas--) Main();
}
05-15 18:28