牛客小白月赛 61 E 排队

 题目大意:

        n个数,共有n!种排列方式,记Pi(a)表示序列a的第i种排队方式,cnt(Pi(a))表示P(i)的逆序对个数,PLMM想知道这n!种排列方式共有多少对逆序对

        给定一个 nnn 个数,在所有排列顺序中每种排列的分别的逆序对总数总数是多少

思路:

        对于互不相等的两数 (a,b),满足 a>b,显然 (a,b)成为逆序对,当且仅当a出现在b之前。所以我们注意到:在 n!次排列下,要么 a 在 b 前面,要么 b 在 a 前面,且两种情况出现的概率都为 1/2​。所以我们对于互不相同的一组 (a,b),计算 (a,b) 的所有排列情况并乘上 1/2即可。

        具体如何计算(a,b)对答案的贡献呢?

        

  1. 对于 a,在未确定位置的 n 个数中它的摆放可以是 n 种
  2. 对于b,在未确定位置的n-1个数种它的摆放可以是n-1种
  3. 所以a,b可以放置的总方案数位n*(n-1),但是需要除以二,因为我们只要大数在前
  4. 剩下的n-2个数,全排列即可(n-2)! 

      由于对于每一个不同的对,处理情况都是一样的,所以只需要统计出来有多少不同的对数,最终乘上一个(n)*(n-1)/2*(n-2)!即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5,mod=1e9+7;

int n,w[N];
int f[N*2];

signed main() {
	f[1]=1;
	for(int i=2; i<=N; i++) {
		f[i]=f[i-1]*i%mod;
	}

	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>w[i];
	}

	sort(w+1,w+1+n);

	if(n==1) {
		cout<<0;
	} else {
		int cnt=0;//记录不同的对数
		for(int i=1; i<=n; i++) {
			int fid=lower_bound(w+1,w+1+n,w[i])-(w+1);//找到第一个大于等于它的数的下标(0------n-1)
			//找到的这个fid就是前面有多少个小于它的
			cnt+=fid;
		}

		int put=(n*(n-1)/2)%mod*f[n-2]%mod;
		//意思是,对于每个对,先找两个位置安排两个数,C(n,2),但是我们只要
		//大数在前的情况,所以除2,另外的数随便安排,这样这个对对答案能贡献多少就算出来了
		//一个有cnt对,所以把所有对加起来就行了
		//因为每个对对答案的贡献是一样的
		//所以
		cout<<(cnt*put+mod)%mod;
	}
	return 0;
}

 

根据用户提供的关键词“小A 弹吉他 网 小白 108 比详情 参攻略”,以下是整合后的相关信息和建议: --- ### 关于小白108的比详情 小白是由网主办的一系列面向编程爱好者的在线竞之一。第108场事通常会围绕算法、数据结构以及实际问题解决能力展开挑战。比题目可能涉及但不限于字符串处理、动态规划、图论等领域。 对于与“小A弹吉他”相关的具体题目,可能是某道以音乐或乐器为主题的趣味性算法题。这类题目往往需要结合数学建模能力和逻辑推理技巧来完成解答。 --- ### 如何准备此类比? #### 方法一:熟悉常见算法模板 确保掌握基础的数据结构(如栈、队列)及经典算法模型(例如深度优先搜索DFS、广度优先搜索BFS)。针对可能出现的音符序列匹配或者节奏计算等问题提前复习KMP模式匹配法等相关知识点。 #### 方法二:模拟真实考场环境练习 利用过往的小白记录进行刷题训练,在规定时间内尝试独立解决问题从而提升临场发挥水平。同时注意控制提交频率避免因超时错误而扣分过多。 #### 方法三:学习优秀选手思路分享 访问社区查看往届高排名玩家的经验贴。他们可能会提到如何快速理解复杂描述型试题的方法论;也可能提供一些特别好用但容易被忽略掉的小技巧比如调试输出设置等细节优化方案。 --- ### 示例代码片段供参考(假设存在一个简单版本的问题) 如果遇到类似判断两个旋律是否相同类型的程序设计,则可以考虑如下实现方式: ```python def is_same_melody(melody_a, melody_b): return melody_a == melody_b melody_A = list(map(int, input().split())) melody_B = list(map(int, input().split())) if len(melody_A) != len(melody_B): print("No") else: if is_same_melody(melody_A,melody_B): print("Yes") else: print("No") ``` 此段落仅为示意用途,请依据实际情况调整适应不同难度等级下的业务场景需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值