2020 CCPC Wannafly Winter Camp Day1 (Div.1&2) 7-1 1A. 期望逆序对

思路很简单,期望逆序对最小肯定是按线段终点排序。

证:两个变量i,j

i是[li,ri]   j是[lj,rj].

想要i尽量小于j,肯定是让i比j小的概率大于1/2.即i的中点小于j的中点

然后n^2枚举求期望即可。

不到半小时写出来过样例,但判断条件错了调了2h。。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod =998244353;
const int M =5000+7;
struct node
{
	ll l,r,mid;
	bool operator < (const node &b)const
	{
		return mid<b.mid;
	}
}sg[M];
ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b/=2;
	}
	return ans;
}
ll inv[M];
int main()
{
	ll n,l,r;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld%lld",&l,&r),sg[i]=node{l,r,l+r};
	sort(sg+1,sg+1+n);
	ll ans=0;
	for(ll i=1;i<=n;i++)inv[i]=qpow(sg[i].r-sg[i].l+1,mod-2);
	ll inv2=qpow(2,mod-2);
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	//让 i段 < j段  即形成一个逆序对 (后面的数小于前面的数)
	{
	//	cout<<i<<" "<<j<<" "<<sg[i].l<<" "<<sg[i].r<<" - "<<sg[j].l<<" "<<sg[j].r<<endl;
		ll li=sg[i].r-sg[i].l+1,lj=sg[j].r-sg[j].l+1,tp=0;
		if(sg[i].r<=sg[j].l)tp=0;
		else if(sg[i].l<=sg[j].l&&sg[i].r<=sg[j].r)//相交  i在左 
		{
		//	cout<<"-1111"<<endl;
			ll lm=sg[i].r-sg[j].l+1;
			tp=(lm-1)*lm%mod*inv2%mod;//一次函数,用中值代替这一段函数的值
		}
		else if(sg[i].l<=sg[j].l&&sg[i].r>=sg[j].r)//包含  i在外
		{
		//	cout<<"-2222"<<endl;
			tp=(lj-1)*lj%mod*inv2%mod;
			tp=(tp+(sg[i].r-sg[j].r)*lj%mod)%mod;			
		}
		else//包含  j在外 
		{
		//	cout<<"-3333"<<endl;
			tp=(li-1)*li/2%mod;
			tp=(tp+li*(sg[i].l-sg[j].l)%mod)%mod;
			//tp=(sg[i].r-sg[j].l+sg[i].l-sg[j].l)*li%mod*inv2%mod;
		}
	//	c/out<<tp<<"  "<<li*lj<<endl;
		ans=(ans+tp*inv[i]%mod*inv[j]%mod)%mod;
	}
	printf("%lld\n",ans);
	return 0;
}
发布了284 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bjfu170203101/article/details/104201684
今日推荐