专栏文章

P8321 『JROI-4』沈阳大街 2 题解

P8321题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mincs3hr
此快照首次捕获于
2025/12/02 00:18
3 个月前
此快照最后确认于
2025/12/02 00:18
3 个月前
查看原文
考虑把 aia_i 看作 11 类数,bib_i 看作 22 类数,将所有 aia_i 和所有 bib_i 扔进一个长度为 2n2n 的数列 cc 中并从大到小排序,每次选出一个 11 类数和 22 类数进行匹配,贡献乘上较小的数的值,将问题转化为求所有匹配方案的贡献之和。
fi,jf_{i,j} 表示考虑到数列 cc 的第 ii 项,此时一共匹配了 jj 对数的方案的贡献的和。转移时,首先根据 i,ji,j 和前缀和数组,计算出未匹配的 11 类数数量 xx 和未匹配的 22 类数数量 yy,再根据 ci+1c_{i+1} 的类型分别处理:
  • ci+1c_{i+1}11 类数:
    • y>0y>0:对 ci+1c_{i+1} 进行匹配,fi+1,j+1fi+1,j+1+y×ci+1×fi,jf_{i+1,j+1} \leftarrow f_{i+1,j+1}+y\times c_{i+1} \times f_{i,j}
    • 不对 ci+1c_{i+1} 进行匹配,fi+1,jfi+1,j+fi,jf_{i+1,j} \leftarrow f_{i+1,j}+f_{i,j}
  • ci+1c_{i+1}22 类数:
    • x>0x>0:对 ci+1c_{i+1} 进行匹配,fi+1,j+1fi+1,j+1+x×ci+1×fi,jf_{i+1,j+1} \leftarrow f_{i+1,j+1}+x\times c_{i+1} \times f_{i,j}
    • 不对 ci+1c_{i+1} 进行匹配,fi+1,jfi+1,j+fi,jf_{i+1,j} \leftarrow f_{i+1,j}+f_{i,j}
初始化 f0,0=0f_{0,0}=0,答案即为 f2n,nf_{2n,n}
时间复杂度 O(n2)\mathcal O(n^2)
C
const int N=5005,mod=998244353;
int n,f[N<<1][N],s[N<<1][3];
pii p[N<<1];
void add(int &a,int b){
	a+=b;
	if(a>=mod) a-=mod;
}
int ksm(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=1ll*res*a%mod;
		b>>=1,a=1ll*a*a%mod;
	}
	return res;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>p[i].fi,p[i].se=1;
	for(int i=1;i<=n;i++) cin>>p[n+i].fi,p[n+i].se=2;
	sort(p+1,p+n+n+1),reverse(p+1,p+n+n+1);
	for(int i=1;i<=n+n;i++) for(int k=1;k<=2;k++) s[i][k]=s[i-1][k]+(p[i].se==k);
	f[0][0]=1;
	for(int i=0;i<n+n;i++){
		for(int j=0;j<=min(s[i][1],s[i][2]);j++){
			int x=s[i][1]-j,y=s[i][2]-j;
			if(p[i+1].se==1){
				if(y>0) add(f[i+1][j+1],1ll*y*p[i+1].fi%mod*f[i][j]%mod);
				add(f[i+1][j],f[i][j]);
			}
			else{
				if(x>0) add(f[i+1][j+1],1ll*x*p[i+1].fi%mod*f[i][j]%mod);
				add(f[i+1][j],f[i][j]);
			}
		}
	}
	int fac=1;
	for(int i=1;i<=n;i++) fac=1ll*fac*i%mod;
	cout<<1ll*ksm(fac,mod-2)*f[n+n][n]%mod<<endl;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...