CFDiv2-Wish I Knew How to Sort-(期望)

60 篇文章 1 订阅

E

题意:
就是给你一个都是0和1的数组,然后每次随机选择两个不同的位置i<j。如果va[i]<va[j],那么交换这两个位置的值,然后问你期望操作操作多少次,可以使得这个数组变成单调不下降数组。

思考:

  1. 又是那种经常考的思维+期望题,肯定不能直接枚举先处理那些0或者1,去硬做。如果期望dp呢?这又没有递推性质,也不是推的。那么应该就是一个思维套在了上面。
  2. 那么既然都是01序列,看看一共有多少1,比如有x个1,那么就看看右边x位中有多少不是1,那么这些位置就是需要换的。比如t位需要换的,那么剩下的t位1肯定也是在左边。每次选择当还需要修改t对的时候,选择一对10的概率就是t*(t-1)/C(n,2)。但是顺序怎么办呢?先处理哪个再处理哪个?这样肯定就复杂了。那么就转化为,还剩下i对要换的时候,换成功一对的期望次数 ,E(x) = 1/p(x)。那么E(总) = E(x)的累加。
  3. 对于期望题,肯定最简单的去处理求概率期望啥的,那种复杂方法肯定是行不通的,最多可以处理数据比较小的数据,可以手玩一下。大部分情况下只要感觉有点复杂,那么就要转化,转化成比较简单的方式。
  4. 其实本题的思维方式,就是问你随机出n个数的期望次数,也是分步之后累加起来。

代码:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
 
using namespace std;
const int mod = 998244353,inf = 1e18;
const int N = 2e5+10,M = 2010;
 
int T,n,m,k;
int va[N];
 
int ksm(int a,int b)
{
	int sum = 1;
	while(b)
	{
		if(b&1) sum = sum*a%mod;
		a = a*a%mod;
		b >>= 1;
	}
	return sum;
}
 
signed main()
{
	IOS;
	cin>>T;
	while(T--)
	{
		cin>>n;
		int mid = 0;
		for(int i=1;i<=n;i++) cin>>va[i],mid += (va[i]==1);
		int sum = 0,ans = 0;
		for(int i=n-mid+1;i<=n;i++) sum += (va[i]==0);
		for(int i=sum;i>=1;i--)
		ans = (ans+n*(n-1)/2%mod*ksm(i*i%mod,mod-2)%mod)%mod;
		ans = (ans%mod+mod)%mod;
		cout<<ans<<"\n";
	}
	return 0;
}

总结:
多多思考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值