题意
给你n个区间, ,在每个区间里面选整数然后要求选出的整数递减的概率
分析
很老的套路了,考虑分母就是
分子的话就是单调递减的dp,右端点+1变成左闭右开离散化之后考虑两个相邻的区间我们怎么选数
下一个区间选的数要在上一个的右边
然后如果在同一个区间里面选数:
如果是整数范围的话就可重复组合,实数范围内的话就是
枚举有多少个数在同一个区间内就好了
代码
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <complex>
#include <iostream>
#include <algorithm>
#define fi first
#define se second
#define MP make_pair
#define PB push_back
#define dmp(x) cout << (x) << endl;
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ll,ll> pii;
const ll N = 110;
const ll mod = 998244353;
const ll inf = 1e15;
inline ll read()
{
ll p=0; ll f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f*=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
ll l[N],r[N],n; ll b[N],blen;
ll f[N][N][N]; ll p[N];
ll qpow(ll x,ll k,ll mo)
{
ll s = 1;
while(k)
{
if(k&1) s = s*x%mo;
x=x*x%mo; k>>=1;
}return s;
}
ll inv(ll x){return qpow(x,mod-2,mod);}
ll C(ll x,ll k)
{
ll s = 1;
if(k==0) return 1;
for(ll i=1;i<=k;i++) s = s * (x-i+1) % mod * inv(i) % mod;
return s;
}
int main()
{
n = read(); blen = 0;
for(ll i=1;i<=n;i++) l[i] = read(),r[i] = read() , b[++blen] = l[i],b[++blen] = ++r[i];
ll fm = 1;
for(ll i=1;i<=n;i++) fm = fm * (r[i] - l[i]) % mod;
sort(b+1,b+blen+1); blen = unique(b+1,b+blen+1) - (b+1);
for(ll i=1;i<=n;i++) l[i] = lower_bound(b+1,b+blen+1,l[i]) - b, r[i] = lower_bound(b+1,b+blen+1,r[i]) - b - 1;
for(ll i=1;i<blen;i++) p[i] = b[i+1] - b[i];
for(ll i=l[1];i<=r[1];i++) f[1][i][1] = p[i];
for(ll i=2;i<=n;i++)
for(ll j=l[i];j<=r[i];j++)
for(ll t=1;t<i;t++)
for(ll k=r[i-1];k>=l[i-1];k--)
{
if(k<j) break;
if(j==k)
{
f[i][j][t+1] = (f[i][j][t+1] + f[i-1][k][t] * inv(C(p[j]+t-1,t)) % mod * C(p[j]+t,t+1) % mod) % mod;
break;
}
else
{
f[i][j][1] = (f[i][j][1] + f[i-1][k][t] * p[j] % mod) % mod;
}
}
ll fz = 0;
for(ll i=1;i<blen;i++)
{
for(ll t=1;t<=n;t++) fz = (fz + f[n][i][t]) % mod;
}
return printf("%lld\n",fz * inv(fm) % mod),0;
}