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

Cisco三层交换机的详细配置

** 本文适用于新手小白以及微微基础的同学来用于参考,实验是在Cisco Packet Tracer Student 进行,实验最终效果如图所示,所有命令配置与图中的一致。 使用到的机器型号为:五台电脑,一台服务器,三个普通交换机(2960型号),一个三层交换机(3560-24PS),两台普通服务器(2811) 文章目录一、什么是三层交换机二、配置交换机步骤1.配置二层交换机2.配置三层交换机3.配置两台路由器以及最后一台电脑 一、什么是三层交换机 1.三层交换机 = 三层路由+二层交换机 2.工作在

真正的大师,永远都怀着一颗学徒的心。 4万+

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

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

小威的专栏 4127

Cursor插件安装CodeX保姆级教程:从登录到调整面板布局,一步不落

本文提供Cursor编辑器安装CodeX插件的详细教程,涵盖从登录到调整面板布局的全流程。通过优化界面布局和配置参数,帮助开发者提升编码效率,特别适合需要智能代码补全的编程场景。

weixin_42648844的博客 4764

RT-Thread Studio使用笔记(四):带片外Flash(W25Q128)的OTA(YModem)

前言 在学习OTA之前,请先参考上两篇博客写的关于SPI设备及W25Q128的使用方法,传送门: https://blog.youkuaiyun.com/tigerots/article/details/107423633 https://blog.youkuaiyun.com/tigerots/article/details/107933991 如何使用OTA 一. 制作BootLoader 打开Bootloader 在线获取地址,注册,并根据RT-thread官方文档生成BootLoader,官方文档已经写的很清楚,再此

tigerots的专栏 4008

poj2299(归并排序求逆序对)

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

weixin_30757793的博客 220

从零编写linux0.11 - 第二章 内核初始化

编程环境:Ubuntu Kylin 16.04 代码仓库:https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载(不能直接编译,需进行修改) 1.添加内核 进入内核后也不是马上进入main函数,上一章只是暂时设置gdt,此外还要设置idt和其他的一些初始化操作,这些内容也要使用汇编进行编写,此处采用AT&T格式的汇编。 以下为head.s的内容,为了简单起见,内容还是一个死循环。 .globl startup_32 startup_3

皓空Fly的博客 1265

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

基于 LSTM 的船舶轨迹预测,单步预测

基于 LSTM 的船舶轨迹预测,单步预测

fyuhao的博客 1万+

uni-app - 最新实现将 uniapp 项目打包编译为 H5 网站,并上传部署到 web 服务器进行发布预览(从打包到发布完整流程步骤,Hbuilder 编译打包 h5 发行到 web 服务器)

uniapp,打包h5,打包编译H5网站,怎么打包h5,uniapp打包成H5部署到服务器教程,uniapp打包H5页面发布到服务器,uniapp开发,打包成H5部署到服务器_uniapp打包h5,uniapp如何打包h5项目,怎么把项目打包成H5,uniapp如何打包成H5并且放到web端上,打包成h5部署到服务器的步骤,打包发行到h5报错怎么办,如何将uniapp打包的h5网站放到服务器上,编译打包后怎么放到web服务器中,如何将uniapp开发的H5打包并部署到服务器,部署使用uniapp开发的h5

🏆 前端领域优质创作者 1万+

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

poj2299

jhsg20080512的博客 358

最新Anaconda3的安装配置及使用教程(详细过程)

最新Anaconda3安装使用Anaconda下载方式一:官网下载方式二:清华镜像下载(推荐)Anaconda安装 Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项 Anaconda + Jupyter 基本上已经是大部分机器学习/数据分析等开发者标配的开发环境, 不多介绍,直接进去正题: Anaconda下载 方式一:官网下载 下载地址传送门: 官网首页:https://www.anaconda.com/ 官网下载页:https://www

HowieXue 薛永浩的博客 34万+

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

OpenCASCADE完整教程专栏完整目录

OpenCASCADE完整教程专栏完整目录

希望我的博客,能帮上你解决学习中工作中所遇到的问题 9703

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

树状数组求逆序对 poj2299

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

weixin_43184669的博客 206

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

poj 2299 树状数组

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

caoxiaoran1202的专栏 407

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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、付费专栏及课程。

余额充值