题解:P12558 [UOI 2024] Heroes and Monsters
Solution
这是人能想出来的吗我请问了。
把英雄看做红球,怪物当做蓝球,在数轴上按照
问对于给定的
很容易发现,标同一种方向的两个球,如果
很容易想到许多
考虑取出第
重要结论:如果最终确实有
所以,我们只需要保证
这样在同一段内,就不需要管另一种颜色是否合法了。这样状态直接被压到
总结:第一,我真的没做出来这道题。
第二,对于这种两种变量的限制问题,限制较为复杂。但是你发现,某一段对一个变量实际上是没有限制的,而另一段对另一个没有限制。那么你就应该把它们分离看。
#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=5000+10,MOD=998244353;
int n,q,a[MAXN],b[MAXN],f[MAXN][MAXN],g[MAXN][MAXN],ans[MAXN];
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;
ffor(i,1,n) cin>>a[i];
ffor(i,1,n) cin>>b[i];
sort(a+1,a+n+1),sort(b+1,b+n+1);
f[0][0]=g[0][0]=1;
ffor(i,1,n) ffor(j,0,i) {
f[i][j]=f[i-1][j];
if(j&&a[i]>b[j]) f[i][j]=(f[i][j]+f[i-1][j-1])%MOD;
}
ffor(i,1,n) ffor(j,0,i) {
g[i][j]=g[i-1][j];
if(j&&a[n-i+1]<b[n-j+1]) g[i][j]=(g[i][j]+g[i-1][j-1])%MOD;
}
ffor(k,0,n) {
int p=0;
while(p+1<=n&&a[p+1]<b[k]) p++;
ffor(x,0,k) {
int y=x+n-p-k;
if(0<=y&&y<=n-p) ans[k]=(ans[k]+f[p][x]*g[n-p][y])%MOD;
}
}
ffor(i,1,n) ans[i]=(ans[i]+ans[i-1])%MOD;
cin>>q;
ffor(i,1,q) {
int l,r,res;
cin>>l>>r,res=ans[r];
if(l) res=(res-ans[l-1])%MOD;
cout<<(res%MOD+MOD)%MOD<<'\n';
}
return 0;
}