首页 > 其他分享 >逆序对的数量 - 题解

逆序对的数量 - 题解

时间:2024-07-29 23:29:46浏览次数:9  
标签:ch 数列 int 题解 mid long 数量 逆序

逆序对的数量

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 64MB,其他语言 128MB

描述

给定一个长度为 \(n\) 的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 \(i\) 个和第 \(j\) 个元素,如果满足 \(i<j\) 且 \(a[i]>a[j]\),则其为一个逆序对;否则不是。
数据范围 \(1≤n≤100000\),数列中的元素的取值范围 \([0,10^9]\)。

输入描述

第一行包含整数 \(n\),表示数列的长度。
第二行包含 \(n\) 个整数,表示整个数列。

输出描述

输出一个整数,表示逆序对的个数。

用例输入 1

6
2 3 4 5 6 1

用例输出 1

5

代码

归并排序 做法

#include<cstdio>
#include<algorithm>
using namespace std;

const int N=1e5+5;
int n,a[N],c[N];
long long ans=0;

void _merge(int l1,int r1, int l2,int r2,int sc)
{
	int p1=l1,p2=l2,p3=sc-1;
	while(p1<=r1 && p2<=r2)
	{
		if(a[p1]<=a[p2])
		{
			c[++p3]=a[p1];
			p1++;
		}
		else
		{
			ans+=(r1-p1+1);
			c[++p3]=a[p2];
			p2++;
		}
	}
	while(p1<=r1) c[++p3]=a[p1], p1++;
	while(p2<=r2) c[++p3]=a[p2], p2++;
	return;
}

void merge_sort(int l,int r)
{
	if(l>=r) return;
	int mid=(l+r)>>1;
	merge_sort(l,mid);
	merge_sort(mid+1,r);
	_merge(l,mid, mid+1,r ,l);
	for(int i=l;i<=r;i++) a[i]=c[i];
	return;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	merge_sort(1,n);
	printf("%lld\n",ans);
	return 0;
}

前缀和+树状数组 做法

#include<cstdio>
#include<algorithm>
using namespace std;

inline int read()
{
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+(ch^'0');
		ch=getchar();
	}
	return x*w;
}

const int N=5e5+5;
int n;
pair<int,int> a[N];
int b[N],bcnt;
long long ans=0;

long long tree[N];
inline int lowbit(int x){return x&-x;}
inline long long ask(int x)
{
	long long res=0;
	for(;x;x-=lowbit(x)) res+=tree[x];
	return res;
}
inline void add(int x,int y)
{
	for(;x<=n;x+=lowbit(x)) tree[x]+=y;
	return;
}

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		a[i].first=read(),a[i].second=i;
	sort(a+1,a+n+1);
	a[0].first=-1;
	for(int i=1;i<=n;i++)
	{
		if(a[i].first==a[i-1].first) b[a[i].second]=bcnt;
		else b[a[i].second]=++bcnt;
	}
	for(int i=n;i>=1;i--)
	{
		ans+=ask(b[i]-1);
		add(b[i],1);
	}
	printf("%lld\n",ans);
	return 0;
}

标签:ch,数列,int,题解,mid,long,数量,逆序
From: https://www.cnblogs.com/jerrycyx/p/18331283

相关文章

  • 求第k小的数 - 题解
    求第k小的数时间限制:C/C++1500MS,其他语言3000MS内存限制:C/C++256MB,其他语言512MB描述输入\(n\)个数字,输出这些数字的第\(k\)小的数。最小的数是第\(0\)小。输入描述第一行包含两个整数\(n(1≤n≤5000000)\)和\(k(0≤k<n)\)。输出描述1个整数(所有整数均在......
  • 最大子段和 - 题解
    最大子段和时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++128MB,其他语言256MB描述给出一个长度为\(n\)的序列\(a\),选出其中连续且非空的一段使得这段和最大。输入描述第一行是一个整数,表示序列的长度\(n\)。第二行有\(n\)个整数,第\(i\)个整数表示序列的第......
  • 数二数 题解
    我们定义\(f_i\)表示考虑\(n=i\)时的答案。考虑怎样才能使得Bob存在一种出题方案使得\(l\)与\(r\)无法确定。假设包含点\(i\)的询问集合为\(S_i\),那么当\(S_l=S_r\)时\(l\)与\(r\)无法确定。发现:如果\(a<b<c<d\),\(S_a=S_c\),\(S_b=S_d\),那么\(S_a=S_b=S_c=......
  • P8314 Parkovi 题解
    题意:树,边有边权,求一种选出\(k\)个点染色的方案,使得每个点到最近的一个被染色点的距离的最大值最小,\(n\le2\cdot10^5\).Solution先看部分分:\(n\le20\):直接\(C_n^k\)爆搜.\(k=1\):对每个点\(u\)求出\(f(u)\)和\(g(u)\)分别表示\(u\)到子树内点距离的最大值、\(u\)......
  • luogu P2371 [国家集训队] 墨墨的等式 题解
    luoguP2371[国家集训队]墨墨的等式题目传送门思路同余最短路同余最短路同余最短路与差分约束有异曲同工之妙,都将约束条件转化为边,每种状态转化为点。把本来与图论毫不相干的问题抽象到具体的图上,通过拓扑排序,最短路等基础算法获得最小状态,从而解决问题。在本题中,以\(0\)......
  • vue3中使用keepAlive缓存路由组件不生效的问题解决
    在Vue3中使用keep-alive缓存路由组件时,可能会遇到一些问题导致缓存不生效。以下是一些常见的问题及其解决方案:keep-alive写法错误:在Vue3中,使用keep-alive需要将router-view包裹在keep-alive中,并通过插槽传递组件。例如:<template><router-viewv-slot="{Co......
  • CF1523D Love-Hate 题解
    CF1523DLove-Hate题解传送门题目大意:给定\(m\)和\(n\)个集合,而且这\(n\)个集合的元素都是\(1\)~\(m\)中的数且没有重复,而且大小都不超过\(15\)。求一个最大的集合,使得这个集合是至少\(\left\lceil\frac{n}{2}\right\rceil\)个集合的子集。先想一个问题:题目是让......
  • CF1523E Crypto Lights 题解
    CF1523ECryptoLights题解传送门。题目大意:有\(n\)个台灯,初始时都是暗的,每次随机点亮一个暗台灯,若点亮后存在一个长度为\(k\)的连续段有大于一个台灯被点亮则立刻停止,求期望点亮多少台灯。(就是直接把原题翻译搬过来了)很明显的期望dp,状态定义也很明显,设\(f_i\)表示......
  • P8347 「Wdoi-6」另一侧的月 题解
    P8347「Wdoi-6」另一侧的月题解第一次自己思考出来紫题,题解纪念一下。下面为大家讲解如何一步步推到最终结论:首先,原树没有根,不妨设它的根为\(1\),将它转化成有根的,便于操作。为了方便描述,我们称将一个非根节点的点的父亲删去,保留含这个点的连通块这个操作为截取操作(就是......
  • CF538G Berserk Robot 题解
    Description有一个机器人,第\(0\)秒时在\((0,0)\)位置。机器人会循环执行一个长度为\(l\)的指令序列,每秒执行一个指令。指令有ULDR四种,分别代表向上/左/下/右移动一格。你不知道这个指令序列具体是什么,但是你知道\(n\)条信息,第\(i\)条信息为「第\(t_i\)秒时机器......