6
2 2
1 2
1 4
1 5
3 5
3 6
输出
405536771
思路
求期望可以用累加每种情况对期望的贡献求得,本题就是用的这个思路。
线段的交取决于最大的左端点以及最小的右端点,同时维护两个东西比较困难。
所以我们先按照线段左端点从大到小排序,存在数组 t l tl tl中,按照线段右端点从大到小排序,存在数组 t r tr tr中。同时还可以离散化一下,节省一下复杂度,然后构建线段树,然后做的操作 : : :
#include
#define ll long long
using namespace std;
const int maxn=2e6+5,mod=998244353,inf=1e9+1,n2=(mod+1)/2;
int n,m=2,t1=1,t2=1,l[maxn],r[maxn],tl[maxn],tr[maxn];
ll ans,p[maxn*2],a[maxn*2],b[maxn*2];
bool cmpl(int x,int y){return l[x]<l[y];}
bool cmpr(int x,int y){return r[x]<r[y];}
void bd(int x,int l,int r)
{
a[x]=p[r+1]-p[l];b[x]=1;
if(l==r)return;
int mid=l+r>>1;
bd(x*2,l,mid);bd(x*2+1,mid+1,r);
}
void f(int x,int l,int r,ll y,int L,int R)
{
if(l<=L&&r>=R){a[x]=a[x]*y%mod;b[x]=b[x]*y%mod;return;}
int mid=(L+R)>>1;
if(l<=mid)f(x*2,l,r,y,L,mid);
if(r>mid)f(x*2+1,l,r,y,mid+1,R);
a[x]=(a[x*2]+a[x*2+1])*b[x]%mod;
}
ll ksm(ll a,ll b){ll c=1;while(b){if(b&1)c=c*a%mod;b>>=1;a=a*a%mod;}return c;}
int main()
{
scanf("%d",&n);p[1]=0;p[2]=inf;
for(int i=1;i<=n;i++)scanf("%d%d",&l[i],&r[i]),p[++m]=l[i],p[++m]=++r[i];
sort(p+1,p+m+1);m=unique(p+1,p+m+1)-p-1;bd(1,1,m-1);
for(int i=1;i<=n;i++)l[i]=lower_bound(p+1,p+m+1,l[i])-p,r[i]=lower_bound(p+1,p+m+1,r[i])-p,tl[i]=i,tr[i]=i;
sort(tl+1,tl+n+1,cmpl);sort(tr+1,tr+n+1,cmpr);
for(int i=1;i^m;i++)
{
while(t1<=n&&l[tl[t1]]<=i)f(1,l[tl[t1]],r[tl[t1]]-1,2,1,m-1),t1++;
while(t2<=n&&r[tr[t2]]<=i)f(1,l[tr[t2]],r[tr[t2]]-1,n2,1,m-1),t2++;
ans=(ans+a[1]*(p[i+1]-p[i]))%mod;
}
ans=(ans+mod-1ll*inf*inf%mod)%mod;
printf("%lld",ans*ksm(n2,n)%mod);
}