首页 > 其他分享 >P1908 逆序对

P1908 逆序对

时间:2024-12-30 21:27:53浏览次数:3  
标签:right P1908 int mid 序列 逆序 left

题目描述

猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。

最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aj​ 且 i<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。

Update:数据已加强。

输入格式

第一行,一个数 n,表示序列中有 n 个数。

第二行 n 个数,表示给定的序列。序列中每个数字不超过 109。

输出格式

输出序列中逆序对的数目。

输入输出样例

输入 #1

6
5 4 2 6 3 1

输出 #1

11

说明/提示

对于 25% 的数据,n≤2500。

对于 50% 的数据,n≤4×10^4。

对于所有数据,n≤5×10^5。

请使用较快的输入输出。

应该不会 O(n2) 过 50 万吧 by chen_zhe。

分析

        我们如果直接选择遍历的话复杂度是O(n^2),就一定会超时。我们需要找的是现在这个数前面有多少个数比它大,要是数组是有序的是不是就会简单很多,那我们就可以想到给它进行排序,一般的排序方法就肯定不行了,那我们比较的时候还要想到和数组原本的顺序还有关系,那我们就只有选择归并排序了。

        那我们现在就需要看看并的操作过程有什么猫腻了,并的过程就是不断地比较S(i)与S(j)的大小较小的存入当我们存入S(j)的时候就说明i一直到mid的值都是大于当前的值,存在(mid-i+1)个,

应为右边的数已经是递增的所以之前不会有比现在更大的数存在。

         代码我们也只是在归并排序的过程中增加了一个ans的变化。

#include<bits/stdc++.h>
using namespace std;
int s[500010]={0};
int tmp[500010]={0};
long long ans=0;
void msort(int left,int right)
{
	if(left==right)
		return;
	int mid=(left+right)/2,i=left,j=mid+1,pos=left;
	msort(left,mid),msort(mid+1,right);
	while(i<=mid&&j<=right)
		if(s[i]<=s[j])
			tmp[pos++]=s[i++];
		else
			tmp[pos++]=s[j++],ans+=mid-i+1;
	while(i<=mid)
		tmp[pos++]=s[i++];
	while(j<=right)
		tmp[pos++]=s[j++];
	for(int k=left;k<=right;k++)
		s[k]=tmp[k];
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&s[i]);
	msort(1,n);
	printf("%lld",ans);
	return 0;
}

标签:right,P1908,int,mid,序列,逆序,left
From: https://blog.csdn.net/2403_87113072/article/details/144834033

相关文章

  • 字符串逆序
    way1:循环版#include<stdio.h>#include<string.h>intmain(){   chararr[]="abcdef";   intleft,right,t;   left=0;   right=strlen(arr)-1;   while(left<right)   {      t=arr[left];      arr[left]=arr[right]; ......
  • LCR 170. 交易逆序对的总数
    交易逆序对的总数在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录record,返回其中存在的「交易逆序对」总数。示例1:输入:record=[9,7,5,4,6]输出:8解释:交易中的逆序对为(9,7),(9,5),......
  • 7-10 sdut- C语言实验-数组逆序(数组移位)
    7-10sdut-C语言实验-数组逆序(数组移位)分数13全屏浏览切换布局作者 马新娟单位 山东理工大学有n个整数,使其最后m个数变成最前面的m个数,其他各数顺序向后移m(m<n<100)个位置。输入格式:输入数据有2行,第一行的第一个数为n,后面是n个整数,第二行整数m。输出格式:......
  • 数组中的逆序对:基于归并排序的高效解法
    问题背景在算法和数据结构领域,"逆序对"是一个经典的计算问题。逆序对定义为数组中前面的元素大于后面的元素的数对。例如,在序列[7,5,6,4]中,存在的逆序对包括:(7,5)(7,6)(7,4)(5,4)(6,4)问题分析问题要求给定一个整数数组,要求计算数组中所有逆序对的总数。暴力解法的局......
  • 逆序对个数
    题目一个数列,如果左边的数大,右边的数小,则称这两个数为一个逆序对。求出一个数列中右多少个逆序对。解法1暴力遍历所有可能的数对。packagecom.company;publicclassTest17{publicstaticvoidmain(String[]args){int[]arr={1 ,4 ,9, 6 ,2, 8, 7 ......
  • 实现字节二进制位逆序的两种方法
    需求:将11010010转变为01001011,可以看出是一个简单的从最低位到最高位的一个倒序需求。网上搜到的都是位运算法,这在计算量大的应用中,一个字节运算8次是非常可耻的。解决问题的办法当然是越简单越好,查表法将一个字节的256种组合放到数组内,用的时候直接从内存取结果,不用运算,但用......
  • 将一个数组逆序输出。-多语言
    目录C语言实现方法1: 交换元素方法2: 使用辅助数组方法3:使用递归 方法4:使用标准库函数(C99及以上)总结Python实现方法1: 交换元素方法2:使用切片 方法3:使用reversed()函数方法4:使用list.reverse()方法方法5:使用for循环和append()......
  • 使用函数输出一个整数的逆序数
    Description本题要求实现一个求整数的逆序数的简单函数。(注意:逆序后去掉前导0)函数接口定义:intreverse(intnumber);其中函数reverse须返回用户传入的整型number的逆序数。Input一行一个整数n。Output一个整数表示答案。SampleInput1 -12340SampleOutput1-4......
  • C++——输入一个字符串,把其中的字符按逆序输出。如输入LIGHT,输出THGIL。用string方法
    没注释的源代码#include<iostream>#include<string.h>usingnamespacestd;intmain(){   stringa;   cout<<"请输入字符串a:";   cin>>a;   intk;   k=a.size();   for(inti=k-1;i>=0;i--)   {       cout<<a[i];......
  • DS堆栈--逆序输出(不使用STL栈)
    题目描述请编写堆栈操作的具体实现代码,实现字符串的逆序输出,需自行实现堆栈。输入一个字符串,按字符按输入顺序压入堆栈,然后根据堆栈后进先出的特点,做逆序输出输入第一行输入t,表示有t个测试实例第二起,每一行输入一个字符串,注意字符串不要包含空格字符串的输入可参考如下......