概率期望,数学,贪心策略——2020-camp-day1-A

/*
区间 [l1,r1][l2,r2] 的形成逆序对的概率 
只考虑相交的情况:三种情况对应的总数tot进行分情况讨论 
这两个区间里取到逆序对的概率是tot/len1*len2 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define ll long long
#define mod 998244353

struct Inv{
    ll l,r,base;
}inv[N];
int cmp(Inv a,Inv b){return a.l+a.r<b.l+b.r;}
ll Pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b%2)res=res*a%mod;
        b>>=1;a=a*a%mod;
    }
    return res;
}

int n;

ll solve(ll i,ll j){
    if(inv[i].r<=inv[j].l)return 0;//逆序对概率为0
    ll R=min(inv[i].r,inv[j].r);
    ll L=max(inv[i].l,inv[j].l);
    ll len=R-L+1,res=0;
    if(inv[i].r>inv[j].r){
        res=len*(len-1)/2%mod;
        res=(res+(inv[i].r-inv[j].r)*(inv[j].r-inv[j].l+1)%mod)%mod;
    } 
    else if(inv[i].r<=inv[j].r && inv[i].l>=inv[j].l){
        res=len*(len-1)/2%mod;
        res=(res+(inv[i].r-inv[i].l+1)*(inv[i].l-inv[j].l)%mod)%mod;
    }
    else if(inv[i].r<=inv[j].r && inv[i].l<inv[j].l){
        res=len*(len-1)/2%mod;
    }
    res=res*inv[i].base%mod*inv[j].base%mod;
    return res;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>inv[i].l>>inv[i].r;
    sort(inv+1,inv+1+n,cmp);
    for(int i=1;i<=n;i++)
        inv[i].base=Pow(inv[i].r-inv[i].l+1,mod-2);
    ll ans=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            ans=(ans+solve(i,j))%mod;
    cout<<ans<<'\n';
}

 
上一篇:[学习笔记]逆元


下一篇:洛谷 P3811 【模板】乘法逆元 线性求逆元