离散化+树状数组 求逆序对数

求逆序对数的方法(归并排序 and 树状数组) 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个序列为4 5 1 3 2, 那么这个序列的逆序数为7,逆序对分别为(4, 1), (4, 3), (4, 2), (5, 1), (5, 3), (5, 2),(3, 2)。 输入描述: 第一行有一个整数n(1 输出描述: 输出这个 阅读详情
除了归并排序,也可以用树状数组求逆序对数。先看 POJ 2299
Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 32606 Accepted: 11633

Description

In this problem, you have to analyze a particular sortingalgorithm. The algorithm processes a sequence of n distinctintegers by swapping two adjacent sequence elements until thesequence is sorted in ascending order. For the inputsequence

9 1 0 5 4 ,

Ultra-QuickSort produces the output
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSortneeds to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every testcase begins with a line that contains a single integer n< 500,000 -- the length of the input sequence. Eachof the the following n lines contains a single integer 0 ≤ a[i] ≤999,999,999, the i-th input sequence element. Input is terminatedby a sequence of length n = 0. This sequence must not beprocessed.

Output

For every input sequence, your program prints asingle line containing an integer number op, the minimum number ofswap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0
 
这里面a[i]的范围是0到999,999,999,太大了,所以要先用离散化缩小范围提高效率(就跟上次那个map的映射差不多,不需要记下来每个数是多大,只要把它排第几那个位置记下来就行了,不影响求逆序对数)。离散化的方法可以是先用结构体记下这个数的大小和初始位置,再对大小进行排序(初始位置跟着大小一起排了),由此得到一个大小有序的数列,同时知道每个数的初始位置。然后用一个数组就可以记住原来每个数的大小应该排在的位置了。假设用b这个数组存,node结构体表示数(node.v是值,node.index是这个数的位置),则排序后如果这个数和上个数不相等,有b[node[i].index]=i,如果相等就是b[node[i].index]=b[node[i-1].index]。这样离散化完成了。

  那什么是树状数组呢?百度百科上的图

  这个貌似有点不好理解,反正记得这些性质:
1.设每个数二进制末尾0的个数是k,则每个数管的数个数就是2的k次方,并且管的最后一个就是自己那个数。比如8的2进制是1000,有3个0,2的3次方是8,则c[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]=a[4]+a[6]+a[7]+a[8]。所以用这种方法求和的话就只用算几个点,不用一个一个加了,节省时间。
2.这个数加上这个数管的个数等于下个管他的数。
  怎么算k呢?下面是百度来的=。= :

算这个2^k有一个快捷的办法,定义一个函数如下即可:
int lowbit(int x){
return x&(x^(x–1));
}
利用机器补码特性,也可以写成:
int lowbit(int x){
return x&(-x);
}

这两个是一样的,^是其中一个是真一个是假就是真,&是两个都真才是真,第一个我也不会解释离散化+树状数组 <wbr>求逆序对数,第二个负数就是取反,加1,比如2是10,取反是01,加1是10,10&10是10,就是2,x&(-x)就是k的值,这个还是很好理解的。。

 然后就可以用这个性质构造树状数组了~按照刚才映射的b数组,每加入一个数就计算此时已经加入的比它大的数的个数,也就是c数组里面加入它的位置的后面有多少个已经存在的数。这也等于总共多少个减去前面有多少个(包括它自己)~
 构造树状数组的方法:假设要把c[i]加1,不光c[i]要加1,管他的那些都要加1。这个数加完1后把这个数加上这个数管的数的个数就是下一个要加1的数。貌似有点绕~哦呵呵。。离散化+树状数组 <wbr>求逆序对数

代码来咯~(有百度参考别人的)
#include<stdio.h>
#include<string.h>
int b[500010],c[500010],N;
typedef struct NNode
{
    int index,v;
} Node;
Node node[500010];
int cmp(const void *a,const void *b)
{
    return (*((Node *)a)).v-(*((Node *)b)).v;
}
int lowbit(int x)  //算k
{
    return x&(-x);
}
void add(int i,int v)  //构造树状数组
{
    while(i<=N)
    {
        c[i]+=v;
        i+=lowbit(i);
    }
}
int sum(int i) //算前面已经有多少个数(包括它自己)
{
    int s=0;
    while(i>0)
    {
        s+=c[i];
        i-=lowbit(i);
    }
    return s;
}
int main()
{
    freopen("D:\\CodeBlocks\\file\\in.txt","r",stdin);
    while(scanf("%d",&N),N)
    {
        int i;
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        for(i=1; i<=N; i++)
        {
            scanf("%d",&node[i].v);
            node[i].index=i;
        }
        qsort(node+1,N,sizeof(node[1]),cmp); //离散化
        b[node[1].index]=1;
        for(i=2; i<=N; i++)
            if(node[i].v!=node[i-1].v)b[node[i].index]=i;
            else b[node[i].index]=b[node[i-1].index];
        long long ans=0;
        for(i=1; i<=N; i++)
        {
            add(b[i],1);
            ans+=sum(N)-sum(b[i]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}



别再只会regress了!用Stata的csdid命令搞定多期DID的完整实操指南 本文详细介绍了如何在Stata中使用csdid命令进行多期DID分析,解决传统DID方法在交错处理场景下的局限性。通过完整的实操指南,包括环境搭建、核心语法、结果解读和高阶应用,帮助研究者更准确地评估政策效果,适用于计量经济学和实证研究领域。 阅读详情

相关推荐

MuJoCo柔性体仿真实战:从FlexComp建模到自定义模型导入

柔性体仿真是机器人交互研究中不可或缺的一环,MuJoCo作为高精度物理求解器,凭借高效的求解速度与批量并行能力,成为强化学习与软体抓取任务的热门选择。其FlexComp机制将连续材料离散为粒子-约束系统,以较低建模成本模拟布料、软组织等形变行为,相比Gazebo等平台更具实时性与可扩展性。技术价值体现在自定义柔性体建模与导入流程中:通过XML配置网格密度、间距与材料参数,即可生成贴合任务需求的软体垫子或硅胶抓手。在柔性抓取、颗粒抓手、医疗仿真等场景中,该方法能快速构建可训练的环境。围绕环境搭建、FlexCo

weixin_29045585的博客 158

树状数组简单总结(原理见以往帖子)

树状数组:快速(动态)求前缀和 在线算法(支持修改) O(logn) 1:给某个位置上的数加上一个增量(修改某个元素) 2:求某个前缀和 即:单点修改,区间查询(sum(r)-sum(l-1)) 树状数组只能支持这俩问题,别的问题都得通过转化才能解决 比如区间修改,单点查询 需要利用差分转化为区间修改 记树状数组为C[x],定义: C[x]=(x-lowbit[x],x],即x-lowbit[x]+1~x,奇数为其本身 lowbit[x]=x&-x,含义是2^k,k为x...

明月千里赴迢遥的博客 681

五子棋AI实战:极大极小搜索、Alpha-Beta剪枝与禁手实现

博弈树搜索是双人零和博弈AI的经典决策框架,其核心思想是假设对手最优应对,通过递归遍历走法空间寻找最优解。极大极小搜索配合Alpha-Beta剪枝,能在不影响决策结果的前提下将搜索量降至平方根级别,大幅提升搜索效率。在五子棋场景中,还需处理黑棋禁手规则,包括双三、双四和长连判定,并将其融入搜索框架。评估函数基于棋型识别对局面打分,走法排序和迭代加深进一步优化剪枝效果。这些技术共同构成了一个可运行的五子棋AI,适用于棋类AI入门与博弈搜索实践。

weixin_29054399的博客 128

树状数组求解逆序对个数(含树状数组的入门)

树状数组(含lowbit的证明)一.树状数组介绍 在学习树状数组之前,我们要先探究4个问题。 1. 什么是树状数组? 见名知意,就是用数组来模拟树形结构。那么又衍生出一个问题,为什么不直接建树呢?这个问题的答案是没有必要,树状数组就可以解决的问题没必要建树。 2. 用来解决什么问题? 和线段树一样用来解决区间上的更新、求和等操作。 3.和线段树有什么区别 其实树状数组可以解决的问题线段树都可以解决,但是树状数组的系数要少很多。 4.优缺点 优点是:修改和查询的时间复杂度都是O(logN),系数要比线段树少许

hahahahahaha5的博客 1201

【架构师面试-缓存与搜索-1】-缓存与缓存置换策略源码实现

1:什么是缓存 缓存:加速数据访问的存储,降低延迟(latency),提升吞吐量(Throughput)的利器。 1:缓存演进历史 1. 查库 2. ConcurrentHashMap 3. LRU 4. Guava Cache 5. 分布式缓存(redis,MemCache) 6. 多级缓存 2:在什么地方加缓存 缓存对于每个开发者来说是相当熟悉了,为了提高程序的性能我们会去加缓存,但是在什么地方加缓存,如何加缓存呢? 举个栗子:假设一个网站,需要提高性能,缓存可以放在浏览器,可以放

chongfa2008的博客 6437

HFSS微带线仿真从零到一:材料参数与求解设置优化指南

在射频电路设计中,微带线仿真涉及电磁场求解与传输线理论,其精度高度依赖材料参数和求解设置。相对介电常数、损耗角正切和导体电导率等参数直接影响特性阻抗与插入损耗,而求解频率、网格划分和参数扫描则决定仿真效率与收敛性。合理设置这些参数可显著提升S参数准确性,避免设计迭代。应用场景包括天线馈线、滤波器和微波互连。本文基于HFSS微带线仿真实践,系统讲解材料选择与参数优化全链路,帮助工程师快速复现可靠模型。

weixin_29192211的博客 79

树状数组求逆序对的方法(学习总结)

逆序对:i<j,a[i]>a[j] 树状数组求逆序对:先把tree置0,每次输入一个数x,用1去更新tree 例如: tree:0 0 0 0 0 x=4: tree: 0 0 0 0 1 然后对x进行查询read(x),可以得到x之前插入了多少个数,因为x之前插入的数都比x小,所以用当前插入的数的总数i减去read(x)可以得到当前插入的i个数中有多少个比x大,即...

qq_43022818的博客 2500

时间序列预测 | 决策树时间序列预测建模,单步、多步(Python)

时间序列预测 | 决策树时间序列预测建模,单步、多步(Python)

天天酷科研的博客 744

树状数组求逆序对数

再清楚地打一边用树状数组求逆序对,记不住就只能多打,万事唯手熟耳。 这里都用的int,实际题目数据要求会不一样,必要时用long long int。这里的一步离散化的作用是如果数列中元素的大小比较大就不易直接开大小范围的树状数组来做,而是先按元素值排序然后比较的是元素原来的index,道理是一样的。 #include &lt;iostream&gt; #include&lt;stdio.h&...

XiaoPANGXia的专栏 1599

JAVA:Spring Boot 集成 LibreOffice 实现文档在线转换服务

本文介绍了在企业级应用开发中使用LibreOffice实现文档格式转换的技术方案。通过对比分析商业库、纯Java方案和云服务API的优缺点,重点阐述了LibreOffice在格式兼容性、转换质量和零成本方面的优势。文章详细说明了环境准备步骤,包括Windows/Linux系统安装LibreOffice、解决中文乱码问题以及Docker部署方案。最后提供了Spring Boot项目的基本配置,包括Maven依赖和application.yml配置文件,为构建稳定高效的文档转换服务奠定基础。

木头 519

AI Agent在医疗诊断中的智能应用研究

本文探讨了AIAgent在医疗诊断中的智能应用,分析了其技术原理、实际案例及发展挑战。AIAgent通过机器学习算法处理医疗数据,提升诊断准确性和效率,市场规模预计2025年达200亿美元。核心技术包括数据预处理、深度学习模型和隐私保护方法。应用案例涵盖肺癌筛查、阿尔茨海默病预测等,但面临数据偏差、伦理责任等挑战。未来趋势包括多模态学习、个性化医疗和量子计算融合。随着技术优化和伦理完善,AIAgent将成为医疗体系的重要组成部分。

郑伟强dev的专栏 96

Ultra-QuickSort 求最小交换次数即求逆序对数 树状数组+离散化

首先介绍一下树状数组 树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组{a}中的元素可能不断地被修改,怎样才能快速地获取连续几个数的和? 传统数组(共n个元素)的元素修改和连续元素求和的复杂度分别为O(1)和O(n)。树状数组通过将线性结构转换成伪树状结构(线性结构只能逐个扫描元素

wjlwangluo的博客 838

微信小程序 - 获取当前日期时间(函数封装)

效果图 前言 摘自微信小程序demo程序中utils.js方法。 普通newDate()出来的日期时间,并不是我们想要的格式,所以要进行格式整理。 解决方案 打开utils.js文件(随意),复制以下代码: /** *获取当前时间 *@description自定义日期分钟秒数 *@param{Object}date-newData()对象 *@returnString */ functionformatTime(date){ //年月日

🏆 前端领域优质创作者 2843

POJ - 2299 Ultra-QuickSort 求逆序对数(树状数组离散化/归并排序)

题目大意:给出一个序列,求将它们冒泡排序的交换次数。 题解:       ①树状数组求逆序对数的一个典例题,但要注意需要离散化,因为n的范围是5e5,而a[i]的范围是1e10,数组开不了1e10那么大,所以离散化一下,只需要开到5e5就可以了 #include&lt;cstdio&gt; #include&lt;iostream&gt; #include&lt;algorithm&g...

hxxjxw的博客 296

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

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

Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 60461 Accepted: 22417 DescriptionIn this problem, you have to analyze a particular sorting algorithm. The algor

STILLxjy 532

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

HDU 4911 Inversion(树状数组求逆序对数 + 数据离散化)

Problem Description bobo has a sequence a1,a2,…,an. He is allowed to swap two adjacent numbers for no more than k times. Find the minimum number of inversions after his swaps. Note: The numb

cxy666 465

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

POJ 2299 Ultra-QuickSort 求原始序列的逆序对数 树状数组+离散化

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 elements until the sequence is sorted i...

深海沧澜的博客 239

牛客---出题人的手环 (离散化 + 树状数组 求逆序对数)

出题人的手环        题目链接:  出题人的手环 树状数组求逆序对数 将尾部的数拿到首部后,逆序对数的变化=原逆序对数+比它小的数的个数–比它大的数的个数 注意:          1, 减完之后可能会出现负数,要加mod后取模。         &

weixin_45705885的博客 400

SGU 180-Inversions(树状数组离散化求逆序对数)

180. Inversions time limit per test: 0.25 sec. memory limit per test: 4096 KB input: standard output: standard   There are N integers (1A[j]. Input The first line of the input contai

crazy_石头的专栏 1122

HDU 4911 Inversion(树状数组)

Inversion Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 7209Accepted Submission(s): 2490 Problem Description bobo has a sequence a...

~ 964

牛客小白月赛 树状数组求逆序对+离散化

链接:https://ac.nowcoder.com/acm/contest/358/D 来源:牛客网 题目描述 出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数。 有一天,出题人和妹子分手了,想把这个手环从两个珠子间切开,并按顺时针顺序展开成一条链。 可以发现,这条链一共有 n 种可能性。求这 n 种可能性的逆序对数之积模 1000000007。 输...

又菜又爱玩 308

poj2299 Ultra-QuickSort&&NYOJ117 求逆序数 (树状数组求逆序对数+离散化)+(归并排序)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 42087   Accepted: 15296 Description In this problem, you have to analyze a particular sorting

听自己心跳的声音 840

浅谈树状数组求逆序对

做了一道树上求逆序对的题,主要难点并不在于树形结构,而是求逆序对数。(在我看来是这样的)。 to洛谷P3605晋升者计数。 发现自己树状数组求逆序对还有个坑,先填上再说。再加上最近学的树状数组离散化,捋一捋思路。 首先是离散化 for(int i=1;i<=n;i++){ a[i].v=read(); a[i].id=i; } sort(a+1,a+1+n);按v排...

weixin_30552811的博客 190

树状数组

引入问题: 我们要输入一个序列a,要求在线修改一个值或者求一个子串的所有元素的和。 1.朴素算法(说白了就是暴力) 修改值:直接改,时间复杂度:O(1) 求字串的所有元素的和:一个循环,时间复杂度:O(n) 有那么有点慢。 2.前缀和 求字串的所有元素的和:一个计算:sun[i]-sum[i-1],时间复杂度:O(1) 修改值:有点麻烦了,要从 i 循环到 n,时间复杂度:O(n) 也有那么有点慢。 综上所述,好像差不了太多呀! 于是,我们的树状数组闪亮登场了! 但在了解树状数组之前,我们先了解一下lowb

sxhlrLX的博客 460

F - Jealous Two「二维偏序」「离散化 + 树状数组」

F - Jealous Two 题目描述: 问满足A[i]>=A[j]A[i] >= A[j]A[i]>=A[j] B[i]<=B[j]B[i] <= B[j]B[i]<=B[j], 1<=i,j<=n1 <= i, j <= n1<=i,j<=n条件的 (i,j)(i, j)(i,j)有多少对 思路: 二维偏序 以 B[i]<B[j]B[i] < B[j]B[i]<B[j]作为第一关键字排序, A[i]>

Suryxin's blogs 294

树状数组求逆序对数小白讲解+poj2299

求逆序对数:最进刚刚学习的树状数组,一直感觉没啥用处,没想到根据树状数组的特殊结构求逆序对数还是挺方便的 题目链接 题意就是求逆序对: 给了n个数,但是数比较分散,所以我们需要用离散化一下,把分散的数转化为为紧凑而且好求的数,然后排一下序,之后求逆序数即可 题解:由于给的数比较散,而且我们求逆序数只需要根据大小来判断逆序对数,所以把分散的数离散化一下,然后根据树状数组求一下逆序数即可 ...

yangzijiangac的博客 252
上一篇: 归并排序求逆序对数
下一篇: 堆 优先队列
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值