POJ2299【树状数组】

【题解】poj2299 树状数组求逆序对+离散化 题目链接 //采用树状数组求逆序对 离散化 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int N=5e5+10; struct node { int p,v; }q[N]; int ... 阅读详情

/* 转载请注明出处, 谢谢 */


目的:理 解 树 状 数 组 的 设 计 思 想 。 /*  在 写 之 前 让 我 先 膜 拜 一 下 ,orz 。 */


1 楼 祭 图:



树状 数 组 , 最 经 典 的 应 用 就 是 求 区 间 和   [ l ,  r ]   的 和 ( 支 持 修 改 操 作 ),为了更好的理解,我们就以这个场景举例子 。 


比 如 对 于 一 个 序列    {   An    } ,我们  用 这样 一 个 数 组   C [ n ]     维 护 : 


C [ i ]     =   A [ i   -   2^ k   +   1 ]    +    A [ i   -   2 ^ k   +   2 ]    +     …   +     A [ 1 ] ;     (A[n] 从下标1开始记)。


  其 中  k  表 示  i    转 换 成二 进 制  后  末 尾 低 位 上 连 续 0 的 个 数  。比 如  i  =  6, 即  1 1 0  (这个数据结构太6,我 要 报 警 啦) , k = 1。 



然  后 我  们  以    { An }  , n  == 8 时 为 例 ,写 出 所 有 的  C[n]:

C[1]  = A[1] ;

C[2]  = A[1] + A[2];

C[3]  = A[3];

C[4]  = A[1] + A[2] + A[3] + A[4];

C[5]  = A[5];

C[6]  = A[5] + A[6];

C[7]  = A[7];

C[8]  = A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7] + A[8]; 

然 后 , 根 据   C [ i ]  的 定 义 定 义 ,可 知 道 每 个   C [ i ]   所   “ 管 辖 ”   的 范 围 就 是,是 啥 呢 ? 这 得 换 成 二 进 制 说 ,假 设 是  i  换 成  二 进 制  是110100,110100 = 110000 + 100,然 后 所 管 辖 的 范 围  就 是 110001  ~ 110100,这 有 什 么 好 处 呢 ? 其 实 这 就 类 似 与 快 速 幂 的 思 想 ,同 样 是 利 用 了 二 进 制

的 性 质 。 



从求和过程观察其原理。下 面 我 们 举 个 栗 子:

我 们 要 算 区 间    [  l ,  r ]  的 和 , 那 么 我 们 首 先 转 化 问 题 :ans  =  sum[ r ] - sum[ l ];  其 中 sum[ i ] , 是 指  区 间  [ 1 ,  i ]  的 和。

那么我们只要考虑  sum[ i ] 怎么算就阔以了。

/*******************************************************************************************************************************************************************************

以 i =  10 举 例 解 释 吧:


1. sum = 0 初 始 化.


2. 我 们 先 转 化 成 二 进 制  i  =  1010,k = 1. C[ i ] 管 辖 的 是   {An} 中 1001 - 1010 的 范 围 . sum += C[ i ];


3. 然 后 我 们 把 i  管 线 的 范 围 剔 除 ,由 上 面 定 义 和 观  察,我 们 已  经 知 道   1010 管 辖 的  是 1001 - 1010 总 共 2 ^ k 大 的 范 围 ,而且他 的 上 限 是  i,

   下 线 是   i - 2 ^ k + 1。


4. 那 我 们 删 去 2^k 后 就 获 得 紧 跟 i 先 下 限 的 的 管 线 范 围 , 即 i  -=   2 ^ k ,  i = 1000,  这 次 i 管 辖 的 就 是 0001 - 1000 了, sum += C[i];


5. 重 复 4 操 作 ,直 到 i == 0, 我 们 获 得 的 就 是[ 1 ,i ]  所 有 的 数的 和。


看 到 没 !! 每 次 操 作 最 少 就 去 掉 一  个 1 !! 。 一 个 数 N ,转 化 成 二 进 制 最 多 有  LogN 个 1 吧  !所   以 每 次 求 和 操 作 的 复 杂 度 是 O(LogN)!!

 *********************************************************************************************************************************************************************************/

是 不 是 跟 快 速 幂 有 异 曲 同 工 之 妙 ? ! 



请仔细思考上述求和操作,然后我们大概说一下点修改操作,类似于上面的操作。

大 概 就 是 对 于  A[ i ] ,  C [ i  + 2 ^k ]  以 及  C[ ( i + 2 ^k ) + 2 ^ k' ] ,( 这 里 是 个 迭  代 过 程 )都 包 含 A [ i ] ;    算了,不说了。上代码了。


 POJ 2299: 

求 长  度 为 N 的 乱  序 数 列 的 逆  序 数,N <= 500000. 

问 题 转 化   为 求  每 个  数 之 前 的 比 它 大 的 数 的 个 数 的 和 。 

记 录 每 个 数 的 位 置 ,按 大 小 排 序 ,然 后 按 照 大 小 插 入 他 们 原 本 的 位 置 当 中 , 即 每 次 更 新 操 作 , 令 a[ val[i].p ] = 1 。

接 着 转 化 ,sum[i] 为 i 之 前 比 a[i] 小 的 数 的 个 数(因 为 按 从 小 到 大 插 入,所 以 比 a[i] 小 的 数 已 经  全 部都 插 入 位 置 了),i - 1为 当 前 已 插 入 自 己 位 置 的 个 数。

i - sum[i] - 1 就 是 在  i 之 前 的 比 a[i ] 大 的 个 数。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int size = 500010;
int N;
struct Val
{
	int p, v;
}val[size];
int C[size];
int cmp(const Val &a, const Val &b)
{
    return a.v < b.v;
}
inline int lowBit(int x)
{
	return x & ( -x );
}
inline int sum(int x)
{
	int ret = 0;
	while(x > 0)
	{
		ret += C[x];
		x -= lowBit(x);
	}
	return ret;
}
inline void update(int x)
{
	while(x <= N)
	{
		C[x] += 1;
		x += lowBit(x);
	}
}
int main(int argc, char const *argv[])
{
	while(scanf("%d", &N) && N)
	{
		long long ans = 0, l , r;

		memset(C,0,sizeof(C));
		for(int i = 1; i <= N; i ++)
		{
			scanf("%d",&val[i].v);
			val[i].p = i;
		}
		sort(val + 1, val + N + 1,cmp);
		for(int i = 1; i <= N; i ++)
		{
		    l = sum(val[i].p);
			r = i - l - 1;
			ans += r;
 			update(val[i].p);
		}
		printf("%lld\n",ans);
	}
	return 0;
}




         

POJ 2299_AC 在这里要用到__int64,也就是long long int 立即下载

相关推荐

POJ2299-Ultra-QuickSort

北大POJ2299-Ultra-QuickSort 解题报告+AC代码

POJ-2299(线段树或树状数组或归并排序)

题目链接: Ultra-QuickSort 思路 刚刚学线性代数学到的逆序数,用多重循环果然超时,刚开始的时候完全没有线段树的思路,后来看了别人的思路,发现真的妙啊,开心的飞起来,虽然我后面又因为把小括号写成中括号的问题WA了一晚上。比如说9 1 0 5 4这个序列,我们记录一下他们的序号位置,然后再排个序: 0 1 4 5 9 在原序列中的位置 3 2 5 4 1 开始我...

“”云腾致雨“”的博客 1823

Cocos Creator 3.x 实战:用脚本动态加载Spine动画,告别resources硬编码

本文详细介绍了Cocos Creator 3.x中Spine动画的动态加载与挂点系统实战技巧。通过Asset Bundle替代传统resources硬编码方式,实现资源的高效管理和热更新支持,同时结合TypeScript强类型和单例模式优化加载流程。文章还深入探讨了跨平台适配、挂点编程方案及性能优化策略,帮助开发者提升游戏开发效率与灵活性。

weixin_42526353的博客 267

Poj-2299 [用归并排序求逆序数的个数]

这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在

小威的专栏 4127

DrMOS电路仿真

将驱动电路与功率MOS集成化后既是DrMOS。把驱动芯片以及上下桥MOSFET封装在一起,这样每一相供电就有了单独的驱动芯片,并且这种高度整合的MOSFET可以通过更高的电流、发热比传统的MOSFET也小很多且更节能 自举升压同步BUCK高低侧栅驱动电路原理及仿真 ...

Srambler的博客 5041

CMN-700组件全解析:从XP路由器到HN-F主节点的实战配置指南

本文深入解析Arm CMN-700片上网络IP的核心组件与实战配置。重点剖析了XP网格路由器的拓扑规划与CHI通道管理,以及HN-F全一致性主节点在维护缓存一致性、管理SLC和地址映射中的关键作用。通过一个12×12网格的配置案例,为硬件工程师提供了从组件布局、地址映射到性能调优的系统级设计指南。

weixin_29313423的博客 284

poj2299(归并排序求逆序对)

题目链接:https://vjudge.net/problem/POJ-2299 题意:给定一个序列,每次只能交换邻近的两个元素,问要交换多少次才能使序列按升序排列。 思路:本质就是求逆序对。我们用归并排序求逆序对,这也是简单的cdq分治。 #include<cstdio> #include<algorithm> #include<cstdli...

weixin_30757793的博客 220

MPN – 制造商物料编号(延伸)

此外,用户还可以在物料主数据中定义阻止MPN材料的原因,以及在采购订单创建时,是否可以将现有的MPN材料修改为其他MPN材料,从而实现对MPN材料的精细控制和管理。通过使用AMPL,用户可以指定每个MPN材料是否仅能为特定工厂或整个企业所有工厂采购、采购的时间段、是否必须属于特定修订级别、是否只能从特定制造商工厂采购以及是否被阻止及其原因。通过AMPL管理,企业可以规范采购流程,避免使用未经批准的材料,从而提高采购的透明度和效率,同时也为质量控制提供了保障‌。3、QM中的制造商物料。质量信息记录QI01。

yanzibing99的博客 2487

POJ_2299(归并排序)

#include #include #include using namespace std; const int MAX = 500001; int value[MAX]; int temp[MAX]; __int64 result = 0; void merge(int left, int mid, int right) { int k = 0; int i=left; int j=mid + 1; while(i

CNnumen 854

华为2024机考真题集合

2.中位数是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数为偶数,那就把中间的两个数之和除以 2,所得的结果就是中位数。在实际考试中会随机抽三道题目进行考察,其中两道100分卷题和一道200分卷题,总共400分。幼儿园组织活动,老师布置了一个任务:每个小朋友去了解与自己同一个小区的小朋友还有几个。3.查找整型数组中元素的众数并组成一个新的数组,求新数组的中位数。1.众数是指一组数据中出现次数量多的那个数,众数可以是多个。

qq_25360769的博客 5093

魔兽世界怀旧服宏命令全解析:从自动换装到智能判定,老玩家才知道的黑科技

本文全面解析魔兽世界怀旧服宏命令的高级应用,从自动换装到智能判定,揭秘老玩家专属的黑科技技巧。深入探讨怀旧服特有的宏命令机制,包括施法队列、装备切换系统和职业专属技巧,帮助玩家在经典旧世版本中提升战斗效率。

weixin_29230865的博客 731

poj 2299(逆序对(树状数组||归并排序))

poj2299

jhsg20080512的博客 358

SPSS因子分析实战:从数据清洗到结果解读的完整流程

本文提供了一份详尽的SPSS因子分析实战指南,涵盖从数据清洗、适用性检验(KMO与巴特利特检验)、公因子提取、因子旋转到结果解读与报告撰写的完整流程。通过具体案例,手把手教你如何利用SPSS进行探索性因子分析,实现数据降维并提炼核心公共因子,适用于市场研究、心理学等多变量数据分析场景。

weixin_29055699的博客 329

poj2299 树状数组+逆序数

题目链接:http://poj.org/problem?id=2299 In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence e...

mumei的博客 266

cdk&java | 绘制含有丰富信息的化学反应(适合论文、网页、PPT)

package org.example; import org.openscience.cdk.DefaultChemObjectBuilder; import org.openscience.cdk.depict.DepictionGenerator; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IReaction; import org.openscience.cdk.

ASKCOS博客 898

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

树状数组求逆序对 poj2299

树状数组求逆序对; 对于一组任意顺序的数,记下他们的初位置,再进行排序,记下他们本来应该在的位置。然后,按最初位置从前往后,进行处理。 基本思想: 对于一个数要求它对应得逆序对,可以通过求前面小于等于它的数的个数,然后用当前已处理的数的个数-前面小于等于当前的数的个数得到。 如: 4 3 5 2 1 排序后 1 2 3 4 5 对于第一个数4,当前处理数的个数为1,本来应该在的位置是4,则在第4个...

weixin_43184669的博客 206

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

poj 2299 树状数组

题目链接:http://poj.org/problem?id=2299 题目大意:本题要用到树状数组的离散化处理,因为数据太大(1-999999999),但还是WA了两次,c[i]的范围计算错误,要用到long long .                从后向前处理,每次处理一个数,求比这个数小的个数。 //poj 2299 树状数组 #include #include #inc

caoxiaoran1202的专栏 407

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

POJ2299 树状数组+离散化

题目地址:http://poj.org/problem?id=2299 学过线代就知道这题就是求逆序数。 逆序数可以用树状数组来解,比方说数字是9,1,0,5,4。那么我就模拟出一个X轴,从左向右读取数字。读取9,则用sum求和比9小的有哪些,那么比9大的个数就是总个数减比9小的,即ans+=(sum(n)-sum(b[i]));这样就可以统计逆序数。 此题数据范围特别大,0 ≤ a

caoyi0905 710

树状数组 求逆序数 poj 2299 离散化

树状数组 求逆序数 poj 2299 这里说的很好,把求逆序的步骤说的很明白,我也是看完才懂的,之前自己想了很久就是不明白为什么可以用树状数组求逆序    转载: 树状数组,具体的说是 离散化+树状数组。这也是学习树状数组的第一题. 算法的大体流程就是: 1.先对输入的数组离散化,使得各个元素比较接近,而不是离散的, 2.接着,运用树状数组的标准操作来累计数组的逆序数。 算法详

The_star_is_at的博客 639

POJ2299 Ultra-QuickSort 树状数组+离散化

题目链接:http://poj.org/problem?id=2299 题目大意: 在某些问题上,你必须分析特定的排序算法。 该算法处理一系列n个不同的整数通过交换两个相邻序列元素,直到按升序排序序列。 对输入序列  9 1 0 5 4, 超快速排序生成的输出  0 1 4 5 9。 你的任务是确定超快速排序需要执行多少互换操作对于给定输入序列。 输入: 测

AC_Gibson的专栏 608

POJ2299-Ultra-QuickSort(树状数组+离散化)

POJ2299 原题链接:http://poj.org/problem?id=2299 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 63588   Accepted: 23705 Description In thi

Yorozuya 555

POJ2299Ultra-QuickSort(树状数组+离散化)

题目链接:POJ2299 题目大意:给你n个数字,问这段序列类似于冒泡排序后至少需要几次交换。 解题思路:实际上就是求数列的逆序数,树状数组可以解决,由于数据规模大到达long long的规模,离散化一下。注意开的val要为long long! AC代码: #include &amp;lt;cstdio&amp;gt; #include &amp;lt;cstring&amp;gt; #include &amp;lt;cstdlib&amp;.

小胡同的诗 213

POJ 2299 Ultra-QuickSort(逆序数 树状数组+离散化)

- POJ 2299 - Ultra-QuickSort Time Limit: 7000MS | Memory Limit: 65536K 题意: 給定一个长度为 n 的数组,用冒泡排序使得它有序,求交换操作的次数;即求该数组的逆序数之和或者逆序对个数。(有多组输入,当 n 为 0 时输入结束) > 逆序数 数据范围: n < 500000,0 ≤ a[i] ≤ 9999999...

Pandora_heart的博客 304

POJ 2299 Ultra-QuickSort(树状数组)

poj 2299题目大意 给一组数,问最少经过多少次相邻交换可以将他们变成升序排列 n<500000;a[i]<999999999; 分析【错误思路】一开始没仔细想太多拿着一个快排算法就开始写了,原本想的是,快排中第一个元素的右边比它小的一定会交换到它的右边,将快拍算法递归中的每一层的第一个元素右边比它小的数的个数加起来的和就是最终答案。样例是过了,其实这样是错误的。 在WA了之后改用树

AIDreamer 376

POJ2299逆序对模板(树状数组)

题目:http://poj.org/problem?id=2299 只能相邻两个交换,所以交换一次只会减少一个逆序对。所以交换次数就是逆序对数。 ps:原来树状数组还可以记录后边lowbit位的部分和。见代码。 #include<iostream> #include<cstdio> #include<cstring> #include<al...

weixin_34004576的博客 138
上一篇: HDU3966【树链剖分】。
下一篇: POJ2114【树分治】
VecSun
博客等级 码龄11年 3粉丝 9原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值