先说一下思路: 先排序 dpi,j=∑s=0nxt[i]dpnxt[i],s×Anxt[i]−sj−s−1 nxt[i] 表示对于第 i 个数,最后一个两倍小于它的数的位置。
再发现这个位置变化的代价是 2 倍,所以应该是 logV(V=1×109) 次。 又因为 nxt[i] 是递增的。
所以变化的时候算一遍。应该是 n2logn 的。 下面附上代码,但是 T 的飞起。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5005;
const int mod =998244353;
int dp[maxn][maxn];
int fac[maxn],inv[maxn];
void init(){
fac[1]=fac[0]=inv[1]=inv[0]=1;
for(int i=2;i<maxn;i++){
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
fac[i]=fac[i-1]*i%mod;
}
for(int i=2;i<maxn;i++){
inv[i]=inv[i-1]*inv[i]%mod;
}
}
int A(int m,int n){
if(m>n) return 0;
return fac[n]*inv[n-m]%mod;
}
int a[maxn],nxt[maxn],last,n,g[maxn],las=-1;
signed main() {
init();
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
while(last<i&&2*a[last+1]<=a[i]) last++;
nxt[i]=last;
}
for(int i=0;i<=n;i++) dp[i][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=nxt[i]+1;j++){
if(las!=nxt[i]){
g[j]=0;
for(int s=0;s<j;s++){
g[j]=(g[j]+dp[nxt[i]][s]*A(j-s-1,nxt[i]-s)%mod)%mod;
}
}
dp[i][j]=dp[i-1][j]+g[j];
if(dp[i][j]=>mod) dp[i][j]-=mod;
}
las=nxt[i];
}
printf("%lld\n",dp[n][n]);
return 0;
}