# 【BZOJ5322】排序游戏（JXOI2018）-贪心

$ans=\frac{n!}{\prod {d}_{i}!}$

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=998244353;
int T,n,m;
ll l,r,a[200010],q[200010];
ll last=1,fac[10200020],inv[10200020];

ll power(ll a,ll b)
{
ll s=1,ss=a%mod;
while(b)
{
if (b&1) s=s*ss%mod;
ss=ss*ss%mod;b>>=1;
}
return s;
}

void calc_fac(ll limit)
{
if (last>=limit) return;
for(ll i=last+1;i<=limit;i++)
fac[i]=fac[i-1]*i%mod;
inv[limit]=power(fac[limit],mod-2);
for(ll i=limit;i>=last+1;i--)
inv[i-1]=inv[i]*i%mod;
last=limit;
}

int main()
{
scanf("%d",&T);
fac[0]=fac[1]=1;
inv[0]=inv[1]=1;

while(T--)
{
int truem;
scanf("%d%d%lld%lld",&n,&m,&l,&r);
truem=m;
calc_fac(n+m);

for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+n+1);

int last=1;
ll ans=1,tot=0;
for(int i=2;i<=n;i++)
{
if (i>1&&a[i]!=a[i-1])
{
if (a[last]>=l&&a[last]<=r)
q[++tot]=i-last;
else ans=ans*fac[i-last]%mod;
last=i;
}
}
if (a[last]>=l&&a[last]<=r)
q[++tot]=n-last+1;
else ans=ans*fac[n-last+1]%mod;
sort(q+1,q+tot+1);

int siz=tot;
tot=r-l+1-tot;
ll lasth=0;
last=siz+1;
for(int i=1;i<=siz;i++)
{
ll v=q[i];
if (m>=(v-lasth)*tot)
{
ans=ans*power(inv[lasth]*fac[v],tot)%mod;
ans=ans*fac[v]%mod;
m-=(v-lasth)*tot;
tot++;lasth=v;
}
else
{
ll A=m/tot,B=m%tot;
ans=ans*power(inv[lasth]*fac[lasth+A],tot)%mod;
ans=ans*power(lasth+A+1ll,B)%mod;
ans=ans*fac[v]%mod;
m=0;
last=i+1;
break;
}
}

if (m)
{
ll A=m/tot,B=m%tot;
ans=ans*power(inv[lasth]*fac[lasth+A],tot)%mod;
ans=ans*power(lasth+A+1ll,B)%mod;
}
else
{
while(siz>=last)
{
ll v=q[siz--];
ans=ans*fac[v]%mod;
}
}

printf("%lld\n",fac[n+truem]*power(ans,mod-2)%mod);
}

return 0;
}
posted @ 2018-05-24 16:37  Maxwei_wzj  阅读(67)  评论(0编辑  收藏  举报