title: 线段树-最小逆序数

date: 2018-10-12 17:19:16

tags:

  • acm
  • 算法
  • 刷题

    categories:
  • ACM-线段树

概述

这是一道简单的线段树的题,,,当然还有很多其他的做法,,,甚至时暴力都可以,,,

用线段树主要是为了在练一练线段树的使用,,,而且这次,,我换了一种写线段树的方法,,,

貌似也是很多大佬都在用的一种写法,,,

之前一直用的入门时为了好理解的一种写法:节点用结构体node表示,,,并且为了理解还添了每一个节点所对应的左右边界,,,

但实际上,,这些信息是没有用的,,,或者说是多余的,,,直接在使用时计算或者直接作为函数的形参传递就行了,,,,

这样的写法代码量更加的少而写写起来也方便,,,占用的空间也少了些,,,

题目的分析

这道题不像之前做的线段树的题那样所维护的值就是最终要求的答案,,,而是中间的某一过程量,,,

首先,,题目的意思就是对于一个给定的数列 \(a_0 , a_1 , a_2 , ,,, ,a_{n-1}\),,,每次将第一个数移动到后面,,,这样一共有n种序列,,,然后对于每一种序列都有一个 逆序数 ,,问你在这些逆序数中最小的那个是多小,,,,

  • 这道题只要知道其中一个序列的逆序数,,它的相邻一个逆序数也就可以推出来,,,具体是这样的:

    \(当已知第i个序列的逆序数sum_i时,,\)

    \(第i+1个序列的逆序数为sum_{i+1}=sum_i + n - a[i] - 1 - a[i],,,,\)

    \(就是说当将第一个数移到最后前,,,\)

    \(它以前的逆序数有 a[i] 个所以要减去这些,,\)

    \(而当它被移到最后时,,,\)

    \(前面又多了 n - a[i] - 1 个,,,\)

    \(最后的sum就求出来了,,,\)

  • 当知道上面这个递推式后,,,我们的任务就是求出所输入出的数列的逆序数,,,然后再根据递推式找出最小的那一个输出就行了,,,

  • 对于求这个数列的逆序数用线段树的方法是,,,先建一个空的数,,,然后每输入一个数,,标记一下,,不过标记在最后的更新完成,,,先求出它之前所输入的所有数中比它大的数(也就是看这个数到n-1一共有几个出现在之前的输入中,,,也就是看标记的和),,,也就是以它构成的逆序列,,,然后把它加(标记)到这个树里(更新),,,可以看出如果把标记改为存放这个数,,纳闷这棵树的叶子节点就是排序好的1~n-1数列,,,,这一段画个图就好理解了,,,

实现

code:

#include <iostream>
#include <cstdio>
#include <cstdlib> using namespace std; #define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r const int maxn = 5005;
int sum[maxn << 2]; void pushup(int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int rt , int l , int r)
{
sum[rt] = 0;
if(l == r)
return; int mid = (l + r) >> 1; build(lson);
build(rson);
pushup(rt);
}
void update(int rt , int l , int r , int loc)
{
if(l == r)
{
++sum[rt];
return;
} int mid = (l + r) >> 1;
if(loc <= mid) update(lson , loc);
else update(rson , loc);
pushup(rt);
}
int query(int rt , int l , int r , int L , int R)
{
if(L <= l && r <= R)
return sum[rt]; int mid = (l + r) >> 1; int ans = 0;
if(L <= mid) ans += query(lson , L , R);
if(R > mid) ans += query(rson , L , R);
return ans;
}
int a[maxn];
int main()
{
int n;
while(scanf("%d" , &n) != EOF)
{
build(1 , 0 , n); int sm = 0;
for(int i = 0; i < n; ++i)
{
scanf("%d" , &a[i]);
sm += query(1 , 0 , n - 1 , a[i] , n - 1);
update(1 , 0 , n - 1 , a[i]);
} int ret = sm;
for(int i = 0; i < n; ++i)
{
sm += n - a[i] - 1 - a[i];
ret = min(sm , ret);
}
printf("%d\n" , ret);
}
}

线段树-最小逆序数hdu1394的更多相关文章

  1. hdu 1394(线段树) 最小逆序数

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 给出一列数组,数组里的数都是从0到n-1的,在依次把第一个数放到最后一位的过程中求最小的逆序数 线段树的应 ...

  2. HDU_1394_Minimum Inversion Number_线段树求逆序数

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  3. hdu 1394 线段树计算逆序数

    线段树计算逆序数的原理: 用线段树来统计已插入的数的个数(所以要保证最大的那个数不能太大,否则数组都开不了),然后每插入一个数,就查询比插入的数大的个数,累加即可. 这个题还有一个特点就是,题目给的是 ...

  4. 【线段树求逆序数】【HDU1394】Minimum Inversion Number

    题目大意: 随机给你全排列中的一个,但不断的把第一个数丢到最后去,重复N次,形成了N个排列,问你这N个排列中逆序数最小为多少 做法: 逆序数裸的是N^2 利用线段树可以降到NlogN 具体方法是插入一 ...

  5. 线段树求逆序数方法 HDU1394&amp;&amp;POJ2299

    为什么线段树能够求逆序数? 给一个简单的序列 9 5 3 他的逆序数是3 首先要求一个逆序数有两种方式:能够从头開始往后找比当前元素小的值,也能够从后往前找比当前元素大的值,有几个逆序数就是几. 线段 ...

  6. hdu1394 Minimum Inversion Number (线段树求逆序数&&思维)

    题目传送门 Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  7. HDU-1394 Minimum Inversion Number(线段树求逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...

  8. HDU - 1394 Minimum Inversion Number (线段树求逆序数)

    Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs ( ...

  9. hdu 1394 (线段树求逆序数)

    <题目链接> 题意描述: 给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找 ...

随机推荐

  1. 20155325 2016-2017-2 《Java程序设计》第6周学习总结

    教材学习内容总结 分类 输入流&输出流 字节流&字符流 节点流&处理流 核心方法 Input Stream int read(byte[]b,int off,int len) ...

  2. 2017中国大学生程序设计竞赛 - 网络选拔赛 1005 HDU 6154 CaoHaha's staff (找规律)

    题目链接 Problem Description "You shall not pass!" After shouted out that,the Force Staff appe ...

  3. 【译】第五篇 Replication:事务复制-How it works

    本篇文章是SQL Server Replication系列的第五篇,详细内容请参考原文. 这一系列包含SQL Server事务复制和合并复制的详细内容,从理解基本术语和设置复制的方法,到描述它是如何工 ...

  4. C# IsAssignableFrom与IsSubClassOf 判断匿名类是否继承父类

    public class Dog : Animal { public string name { get; set; } } public class Animal { public string i ...

  5. 被我误解的max_connect_errors【转】

    实为吾之愚见,望诸君酌之!闻过则喜,与君共勉 第一节  什么是max_connect_errors 一开始接触这个参数的时候,感觉他和max_connections的含义差不多,字面意思简单明了,这个 ...

  6. C#利用System.Net发送邮件

    啥也不说了,直接上干货 using System.Net.Mail;using System.Net; //使用发送邮件的邮箱 var emailAcount = "826217795@qq ...

  7. jQuery简单介绍

    一.jQuery介绍 jQuery是一个轻量级的.兼容多浏览器的JavaScript库. jQuery使用户能够更方便地处理HTML Document.Events.实现动画效果.方便地进行Ajax交 ...

  8. 从一个局长使用BS系统的无奈看测试点

    今天我点名买了个B/S系统,听说只要有浏览器就能用.我最讨厌装客户端了,用浏览器就是方便啊. 下面就是我使用这个系统碰到的麻烦事: 我登录失败的时候没有任何提示,这没什么,反正提示也只是说失败…… 进 ...

  9. GMM 模型需不需归一化问题

    工作中遇到的问题:在GMM模型中添加一维scale比较大的特征,需不需要归一化 答案:不需要,推导如下:

  10. ASP .Net Core系统部署到 CentOS7 64 具体方案

    .Net Core 部署到 CentOS7 64 位系统中的步骤 1.安装工具 1.apache 2..Net Core(dotnet-sdk-2.0) 3.Supervisor(进程管理工具,目的是 ...