一个不知道为什么T的做法(应该是n^2log的)
查看原帖
一个不知道为什么T的做法(应该是n^2log的)
913131
Skicyer楼主2023/11/9 08:44

先说一下思路: 先排序 dpi,j=∑s=0nxt[i]dpnxt[i],s×Anxt[i]−sj−s−1dp_{i,j}=\sum_{s=0}^{nxt[i]}dp_{nxt[i],s}\times A_{nxt[i]-s}^{j-s-1} nxt[i]nxt[i] 表示对于第 ii 个数,最后一个两倍小于它的数的位置。

再发现这个位置变化的代价是 22 倍,所以应该是 log⁡V(V=1×109)\log V(V=1 \times 10^9) 次。 又因为 nxt[i]nxt[i] 是递增的。

所以变化的时候算一遍。应该是 n2log⁡nn^2 \log n 的。 下面附上代码,但是 TT 的飞起。

#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;
}
2023/11/9 08:44
加载中...