PKU 2299 求解逆序数(使用归并或者树状数组) 树状数组及入门知识

归并ac代码为:

#include <iostream>
#include <fstream>
using namespace std;

#define MAX 500005
int a[MAX], t[MAX];
__int64 cnt;

void Merge(int l, int mid, int r)
{
	int i = l, j = mid + 1, k = 0;
	while(i <= mid && j <= r) {
		if(a[i] > a[j]) {
			t[k++] = a[j++];
			cnt += mid - i + 1;
		} else {
			t[k++] = a[i++];
		}
	}
	while(i <= mid) t[k++] = a[i++];
	while(j <= r) t[k++] = a[j++];
	for(i = 0; i < k; i++)
		a[l+i] = t[i];
}

void MergeSort(int l, int r) 
{
	int mid = (l + r) / 2;
	if(l < r) {
		MergeSort(l, mid);
		MergeSort(mid+1, r);
		Merge(l, mid, r);
	}
}

int main()
{
	int n, i;
	while(scanf("%d", &n) != EOF && n) {
		for(i = 0; i < n; i++) 
			scanf("%d", &a[i]);
		cnt = 0;
		MergeSort(0, n-1);
		printf("%I64d\n", cnt);
	}
	return 0;
}


树状数组主要是这张图片:



inline int Lowbit(int x)
{
	return x & (-x);
}
void Update(int x, int c)
{
	int i; 
	for (i = x; i < maxn; i += Lowbit(i))
	{
		tree[i] += c; 
	}
}
int Getsum(int x)
{ 
	int i;
	int temp(0); 
	for (i = x; i >= 1; i -= Lowbit(i))
	{ 
		temp += tree[i]; 
	}
	return temp;
}
以上三个函数可以说是树状数组的“看家本事”,树状数组的高效就体现在这三个函数上了。

Lowbit(x),是求出2^p(其中p为x的二进制表示中最右边的那个1的位置),如6的二进制表示为110,最右边的1为1,故Lowbit(6) = 2^1 = 2。
Update(x, c),是使x这点的值改变c,如果是一般数组改变的就是x自己这点,但是树状数组中要把(x, x+Lowbit(x), x+Lowbit(x+Lowbit(x))),…)这条路径的点都要改变c,这样做是为了后面能够高效地求和。(注意x的值可能是实际的值,也可能是数组的下标,如果太大的话需要离散化
Getsum(x), 是求的(1, …x-Lowbit(x-Lowbit(x))), x-Lowbit(x), x)这条路径的点的和,换句话说就相当于求一般数组a[1]到a[x]的和。

树状数组的高效就在于: 与一般数组不同,一般数组都是下标不断加一来遍历的,而树状数组是不断加2^p来变化的,故效率为(logn)级别的。


树状数组的最基本功能就是求比某点x小的点的个数(这里的比较是抽象的概念,可以使数的大小,坐标的大小,质量的大小等)。
比如给定个数组a[5] = {2, 5, 3, 4, 1},求b[i] = 位置i左边小于等于a[i]的数的个数.如b[5] = {0, 1, 1, 2, 0},这是最正统的树状数组的应用,直接遍历遍数组,每个位置先求出Getsum(a[i]),然后再修改树状数组Update(a[i], 1)即可。当数的范围比较大时需要进行离散化,即先排个序,再重新编号。如a[] = {10000000, 10, 2000, 20, 300},那么离散化后a[] = {5, 1, 4, 2, 3}。(本题就是这个例子)

详细资料:http://download.csdn.net/detail/vsooda/4985249


#include <iostream>
#include <algorithm>
#define MAX 500010
using namespace std;

typedef struct ARR{
	int n,ind;
}ARR;
ARR a[MAX];
long long sum;
int c[MAX],aa[MAX]; //c保存交换次数, aa保存离散化结果
bool cmp( ARR a, ARR b )
{
	return a.n > b.n;
}
int Lowbit(int x)
{
	return x & (-x);
}
void Update(int x)
{
	while( x < MAX )
	{
		c[x]++;
		x += Lowbit(x);
	}
}
int Getsum(int x)
{
	int sum = 0;
	while( x > 0 )
	{
		sum += c[x];
		x -= Lowbit(x);
	}
	return sum;
}
int main()
{
	int n,i,tmp;
	while( ~scanf("%d",&n) && n )
	{
		sum = 0ll;
		memset(c,0,sizeof(c));
		for(i=1; i<=n; i++)
		{
			scanf("%d",&a[i].n);
			a[i].ind = i; //记住下标
		}

		sort(a+1,a+n+1,cmp);

		int p = 1;
		aa[ a[1].ind ] = p;
		tmp = a[1].n;
		for(i=1; i<=n; i++) //离散化
		{
			if( a[i].n == tmp )
				aa[ a[i].ind ] = p;
			else
			{
				tmp = a[i].n;
				p++;
				aa[ a[i].ind ] = p;
			}
		}
		for(i=1; i<=n; i++)
		{
			sum += Getsum(aa[i]);
			Update(aa[i]);
		}
		printf("%lld\n",sum);
	}
	return 0;
}

内容概要:本文详细介绍了一个基于黏菌优化算法(SMA)优化的Transformer-LSTM组合模型在多变量回归预测中的完整项目实例。项目通过融合Transformer的全局特征提取能力与LSTM的局部时序建模优势,构建层次化混合模型,并引入SMA算法实现超参数自动寻优,提升模型性能与泛化能力。项目涵盖数据预处理、模型设计、训练优化、结果评估、GUI可视化界面开发及工程化部署全流程,配套完整代码与目录结构设计,支持端到端自动化建模与跨平台应用。; 适合人群:具备一定机器学习和深度学习基础,熟悉Python编程与PyTorch框架,从事数据科学、人工智能研发或工程落地的相关技术人员,尤其是工作1-3年希望提升模型自动化与实战能力的研发人员。; 使用场景及目标:①应用于智能制造、金融风控、智慧医疗、能源管理、气象预测、智能交通等多变量时间序列预测场景;②掌握Transformer与LSTM融合建模方法;③学习SMA等群体智能算法在深度学习超参数优化中的实际应用;④实现从数据处理到模型部署的全流程自动化开发。; 阅读建议:建议结合文档中的代码示例与GUI实现部分动手实践,重点关注模型架构设计、SMA优化机制和训练流程细节,配合可视化分析深入理解模型行为。同时可扩展尝试不同数据集和优化算法,提升对复杂时序预测任务的综合把控能力。
【源码免费下载链接】:https://renmaiwang.cn/s/bu4rv 在MATLAB中,散点图是一种非常常用的可视化工具,它能够帮助我们理解两个或多个变量之间的关系。散点图通过在二维平面上用点的位置来表示数据,其中x轴和y轴分别代表不同的变量,点的位置则对应着数据点在两个变量上的值。这种图表在数据分析、科学研究以及工程应用中都有着广泛的应用。标题"liwei.zip_matlab散点图_matlab画散点_matlab画散点图_散点图"表明这个压缩包包含了与使用MATLAB绘制散点图相关的资源。可能包含一个MATLAB脚本文件(liwei.m)和一个图像文件(B.jpg),前者是用于创建散点图的代码,后者可能是运行脚本后生成的示例散点图。描述中的"画多张散点图,虽然简单点,但很实用啊,希望对大家能有帮助,哈哈"暗示了这个MATLAB脚本可能不仅展示了如何绘制单个散点图,还可能涉及如何生成多个散点图或者在一个图形窗口内绘制多组数据。这样的功能对于比较不同数据集或展示变量间复杂关系非常有用。在MATLAB中,绘制散点图的基本命令是`scatter`。例如,如果我们有两个向量`x`和`y`,我们可以用以下代码创建一个简单的散点图:```matlabx = 1:10; % 创建一个1到10的向量y = x.^2; % y的值为x的平方scatter(x, y); % 绘制散点图````scatter`函数可以接受额外的参数,比如颜色、大小和标记样式,以定制散点的外观。例如,我们可以为不同的数据集使用不同的颜色:```matlabx1 = 1:5;y1 = x1.^2;x2 = 6:10;y2 = x2.^3;colors = {r, b}; % 设置两种颜色scatter(x1, y1, r); % 绘制第一组数据,红色hold on; % 保持当前图形,允许在同一图上
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值