欢迎使用CSDN-markdown编辑器!

2021.3.21

T1

题意:给出序列n个数的值域区间,求此序列的期望逆序对数

题不是很难,考虑计算第 j j j个数对第 i i i个数产生的期望贡献

分类讨论

  1. l i ≤ l j ≤ r i < r j l_i\leq l_j \leq r_i < r_j liljri<rj

( r j − r i ) → ( r j − l j ) & ( l j − l i ) ( r j − l j ) ( 2 r j − r i − l j ) ( r i − l j ) 2 + l j ( r j − l j ) − l i ( r j − l j ) ( r i − l i ) ( r j − l j ) = ( 2 r j − l j ) ( r i − l j ) − r i ( r i − l j ) 2 + l j ( r j − l j ) − l i ( r j − l j ) ( r i − l i ) ( r j − l j ) = 2 r i r j − ( 2 r j − l j ) l j − r i 2 2 + l j ( r j − l j ) − l i ( r j − l j ) ( r i − l i ) ( r j − l j ) (r_j-r_i)\rightarrow(r_j-l_j)\And(l_j-l_i)(r_j-l_j)\\ {{(2r_j-r_i-l_j)(r_i-l_j)\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\ ={{(2r_j-l_j)(r_i-l_j)-r_i(r_i-l_j)\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\ ={{2r_ir_j-(2r_j-l_j)l_j-r_i^2\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_i-l_i)(r_j-l_j)}\\ (rjri)(rjlj)&(ljli)(rjlj)(rili)(rjlj)2(2rjrilj)(rilj)+lj(rjlj)li(rjlj)=(rili)(rjlj)2(2rjlj)(rilj)ri(rilj)+lj(rjlj)li(rjlj)=(rili)(rjlj)22rirj(2rjlj)ljri2+lj(rjlj)li(rjlj)

  1. l j < l i ≤ r j ≤ r i l_j<l_i\leq r_j\leq r_i lj<lirjri

0 → ( r j − l i ) ( r j − l i ) 2 2 ( r j − l j ) ( r i − l i ) = r j 2 + l i 2 − 2 l i r j 2 ( r j − l j ) ( r i − l i ) = r j 2 + ( l i 2 − 2 l i r j ) 2 ( r j − l j ) ( r i − l i ) 0\rightarrow (r_j-l_i)\\ {(r_j-l_i)^2\over 2(r_j-l_j)(r_i-l_i)}\\ ={r_j^2+l_i^2-2l_ir_j\over 2(r_j-l_j)(r_i-l_i)}\\ ={r_j^2+(l_i^2-2l_ir_j)\over 2(r_j-l_j)(r_i-l_i)} 0(rjli)2(rjlj)(rili)(rjli)2=2(rjlj)(rili)rj2+li22lirj=2(rjlj)(rili)rj2+(li22lirj)

  1. l i ≤ l j < r j ≤ r i l_i\leq l_j<r_j\leq r_i lilj<rjri

0 → ( r j − l j ) ∣ ( l j − l i ) ( r j − l j ) ( r j − l j ) 2 2 + l j ( r j − l j ) − l i ( r j − l j ) ( r j − l j ) ( r i − l i ) 0\rightarrow (r_j-l_j)|(l_j-l_i)(r_j-l_j)\\ {{(r_j-l_j)^2\over 2}+l_j(r_j-l_j)-l_i(r_j-l_j)\over (r_j-l_j)(r_i-l_i)} 0(rjlj)(ljli)(rjlj)(rjlj)(rili)2(rjlj)2+lj(rjlj)li(rjlj)

  1. l j < l i < r i < r j l_j<l_i<r_i<r_j lj<li<ri<rj

( r j − r i ) → ( r j − l i ) ( 2 r j − l i − r i ) ( r i − l i ) 2 ( r j − l j ) ( r i − l i ) = 2 r j ( r i − l i ) − ( l i + r i ) ( r i − l i ) 2 ( r j − l j ) ( r i − l i ) (r_j-r_i)\rightarrow (r_j-l_i)\\ {(2r_j-l_i-r_i)(r_i-l_i)\over 2(r_j-l_j)(r_i-l_i)}\\ ={2r_j(r_i-l_i)-(l_i+r_i)(r_i-l_i)\over 2(r_j-l_j)(r_i-l_i)} (rjri)(rjli)2(rjlj)(rili)(2rjliri)(rili)=2(rjlj)(rili)2rj(rili)(li+ri)(rili)

  1. r i < l j r_i< l_j ri<lj

    直接查

下面这份代码因实现的问题可能会被卡时空,但是它是对的

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;char k;bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define mod 998244353ll
# define inv2 499122177ll
struct A{
	int x,y;
	A(int _x=0,int _y=0):x(_x),y(_y){}
	A& operator +=(const A &b){return (x+=b.x)>=mod&&(x-=mod),(y+=b.y)>=mod&&(y-=mod),*this;}
	A& operator -=(const A &b){return (x-=b.x)<0&&(x+=mod),(y-=b.y)<0&&(y+=mod),*this;}
	A operator +(A b)const{return b+=*this;}
	A operator -(A b)const{return A(x,y)-=b;}
};
struct B{
	int x,y,z;
	B(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z){}
	B& operator +=(const B &b){return (x+=b.x)>=mod&&(x-=mod),(y+=b.y)>=mod&&(y-=mod),(z+=b.z)>=mod&&(z-=mod),*this;}
	B& operator -=(const B &b){return (x-=b.x)<0&&(x+=mod),(y-=b.y)<0&&(y+=mod),(z-=b.z)<0&&(z+=mod),*this;}
	B operator +(B b)const{return b+=*this;}
	B operator -(B b)const{return B(x,y,z)-=b;}
};
Type struct node{
	node *l,*r;
	T v;
	node():v(){l=r=NULL;}
};
node<B>*a[200005],*b[200005];
node<A>*d[200005],*c[200005],*g[200005];
int s;
Type void add(node<T>*& x,int w,T v,int l,int r){
	if(!x)x=new node<T>;
	x->v+=v;
	if(l==r)return;
	int mid=l+r>>1;
	if(w<=mid)add(x->l,w,v,l,mid);
	else add(x->r,w,v,mid+1,r);
}
Type T query(node<T>* x,int l,int r,int tl,int tr){
	if(r<l)return T();
	if(!x)return T();
	if(l==tl&&r==tr)return x->v;
	int mid=tl+tr>>1;
	if(r<=mid)return query(x->l,l,r,tl,mid);
	if(mid<l)return query(x->r,l,r,mid+1,tr);
	return query(x->l,l,mid,tl,mid)+query(x->r,mid+1,r,mid+1,tr);
}
int fu[200005];
Type void add(node<T> **a,int x,int y,T t){while(x<=*fu)add(a[x],y,t,1,*fu),x+=x&-x;}
Type T query(node<T> **a,int x,int l,int r){
	T t;
	while(x)t+=query(a[x],l,r,1,*fu),x&=x-1;
	return t;
}Type T query(node<T> **a,int xl,int xr,int l,int r){return query(a,xr,l,r)-query(a,xl-1,l,r);}
ll qkpow(ll n,ll m){
	ll t=1;
	for(;m;m>>=1){
		if(m&1)t=t*n%mod;
		n=n*n%mod;
	}
	return t;
}
pair<int,int>q[100005];
int main(){fre("rng");
	s=read;ll t=0,ans=0;B k(0,0,0);A v(0,0);
	for(int i=1;i<=s;++i)fu[++fu[0]]=read,fu[++fu[0]]=read,q[i]=make_pair(fu[fu[0]-1],fu[fu[0]]);
	sort(fu+1,fu+*fu+1);
	*fu=unique(fu+1,fu+*fu+1)-fu-1;
	for(int i=1;i<=s;++i){
		int l=q[i].first,r=q[i].second,xl=lower_bound(fu+1,fu+*fu+1,l)-fu,xr=lower_bound(fu+1,fu+*fu+1,r)-fu;
		k=query(a,xl,xr,xr+1,*fu);
		t=(t+k.x+1ll*r*k.y-1ll*l*k.z-inv2*r%mod*r%mod*query(d,xl,xr,xr+1,*fu).y)%mod;
		k=query(b,xl,xr,1,xl-1);
		t=(t+k.x+inv2*l%mod*l%mod*k.z-1ll*l*k.y)%mod;
		v=query(c,xl,xr,xl,xr);
		t=(t+v.x-1ll*l*v.y+mod)%mod;
		v=query(d,1,xl-1,xr+1,*fu);
		t=(t+1ll*(r-l)*v.x-inv2*(l+r)%mod*(r-l)%mod*v.y)%mod;
		ll tv=qkpow(r-l,mod-2);
		add(a,xl,xr,B((1ll*l*(r-l)+(mod-2*r+l)*l%mod*inv2)%mod*tv%mod,r*tv%mod,(r-l)*tv%mod));
		add(b,xr,xl,B(1ll*r*r%mod*tv%mod*inv2%mod,r*tv%mod,tv));
		add(c,xl,xr,A((inv2*(r-l)%mod*(r-l)+1ll*l*(r-l))%mod*tv%mod,(r-l)*tv%mod));
		add(d,xl,xr,A(r*tv%mod,tv));
		ans=(ans+t*tv)%mod;
		v=query(g,xr+1,*fu,xr+1,*fu);
		ans=(ans+v.x)%mod;
		add(g,xl,xr,A(1));t=0;
	}printf("%lld\n",(ans+mod)%mod);
	return 0;
}

虽然可以用差分改成 n log ⁡ 2 n n\log_2n nlog2n,但我这份打的是 n log ⁡ 2 2 n n\log_2^2n nlog22n的树套树 ☕️

考场上头铁了,所以就盯着这道题打。debug不出来,想打下道题,但是一想到已经打出来了,就不由得不爽了起来,所以我就收获了0分的好成绩😄

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值