小陶与杠铃片

题目描述

小陶在举重队负责后勤工作。举重队的训练场中有一个区域一排码放了n片杠铃片,每天运动员们训练完之后会将杠铃片放回,之后小陶需要重新整理杠铃片的顺序,使它们由轻到重依次排好。由于杠铃片很重,小陶每次只能选两片相邻的杠铃片,交换它们的位置。现在小陶想知道,这一天他至少需要交换多少次才能整理完毕?

已知n<=200000,0<=杠铃片重量<=200000。

输入格式

第一行一个正整数n,表示有n片杠铃片;

第二行n个整数,表示运动员们放回后每片杠铃片依次的重量。

输出格式

输出一个整数,表示小陶至少交换的次数。

样例

【样例输入】

复制代码
10
16808 75250 50074 143659 108931 11273 27545 50879 177924 37710

【样例输出】

复制代码
20
数据范围与提示

对于30%的数据: n<=5000 对于60%的数据:

n<=30000 对于100%的数据:

n<=200000,0<=杠铃片重量<=200000

一些想法

这道题依旧用树状数组做,这道题其实就是求冒泡排序的交换次数,也就是求有多少对逆序对。

简单来说,就是找一个数前面有多少个数比他大,然后将个数全部加起来,就得到要交换的次数了。是一种前缀查询,所以用树状数组做最好。

先定义一个树状数组用于储存前缀和(小于当前重量元素的数量)。然后主函数部分:因为输入数有可能是 0,所以要整体偏移加 1(避免死循环),然后答案累加已处理的数的数量( i-1 )减小于当前重量的元素个数,也就是累加要交换的次数(已处理个数减小于当前重量的元素个数,剩下的就是在当前数前面但大于当前数的元素个数,也就是要交换的次数),这里要用到查询小于当前数的元素个数(查询函数)。然后将当前数放进树状数组里,为后续查询提供数据。这就要用到修改数组。而这两个自定义数组都要用 lowbit 数组来划分区间。

函数部分,有三个自定义函数:

lowbit 函数:用位运算找 x 二进制的最后一个 1 。树状数组的所有操作都基于 lowbit 实现区间划分。

查询函数:查询 比 x 小的元素个数(前缀和查询),然后只要 x 大于 0(没有超出范围),然后将 x 不断减小(减自己的lowbit),跳转到前一个区间,将个数增加。(简单来说就是分解,将当前区间不断分解成多个小区间)。

修改函数:将第 x 个数增加 y ,因为前面的点有变化,所以包含这个点的在范围内的所有数都要跟着变化,因为父节点要随着子节点的变化而变化,所以每次增加自己的 lowbit ,也就是不断往后一个区间,直到达到边界,然后每一个区间都增加指定值。

注意:统计交换次数的数组要开 long long!!!

因为测试数据会很大,如果不开 long long 会出现越界行为,导致程序崩溃或答案错误。

AC代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,c[200005],x;
long long sum=0;
const int N=200020;
int lowbit(int x){
	return x&-x;
}
int zs(int x){
	int cnt=0;
	for(;x>0;x-=lowbit(x)){
		cnt+=c[x];
	}
	return cnt;
}
void sm(int x,int y){
	for(;x<N;x+=lowbit(x)){
		c[x]+=y;
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x;
		x++;
		sum+=(i-1)-zs(x);
		sm(x,1);
	}
	cout<<sum;
	return 0;
}
相关推荐
进化中的刀盾兽1 小时前
从零实现 C++ Json-Rpc(十):把消息交给真实连接——MuduoConnection 与 ConnectionFactory
c++·rpc
青瓦梦滋8 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
CodeYp201913 小时前
第15讲:二叉搜索树
开发语言·c++·二叉搜索树
shehuiyuelaiyuehao13 小时前
算法56,重排链表
数据结构·算法·链表
pipixia2003314 小时前
C++继承面试四连问:内存叠加、私有继承、sizeof、权限重映射
c++·面试·嵌入式·继承·面向对象·对象模型
suhan15 小时前
【数据结构】七、查找:1.查找的概念、线性结构查找(顺序、折半(二分)、插值、稠密、分块、倒排)
数据结构·算法·排序算法
极客 - L U15 小时前
卡尔曼滤波从零到精通
c语言·数据结构·单片机·嵌入式硬件·mcu
牵猫散步的鱼儿16 小时前
C++ 内存分区
c++
choumin17 小时前
C++ 标准容器为什么不能存引用
c++·容器·引用类型
谙弆悕博士17 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室