<Sicily>Inversion Number(线段树求逆序数)
一、题目描述
There is a permutation P with n integers from 1 to n. You have to calculate its inversion number, which is the number of pairs of Pi and Pj satisfying the following conditions: iPj.
二、输入
The input may contain several test cases.
In each test case, the first line contains a positive integer n (n<=100000) indicating the number of elements in P. The following n lines contain n integers making the permutation P.
Input is terminated by EOF.
三、输出
For each test case, output a line containing the inversion number.
四、解题思路
题意:求逆序
思路:
1.对整个输入序列,从前往后扫,统计比a[i]小的,在a[i]后面的有多少个,进行累加。这种方法是暴力做法。复制度为n^2。
2)统计a[i]前面的比它大的数
这样利用输入时,已经知道前面的序列,每输入一个数,就把这个数的num[i]值加1,然后统计比这个数大的数的num和,因为这里的和一定是在这个数列中比a[i]大,且在它前面出现的数之和,再把这个和加到总逆序数sum里。
3)在统计比这个数大的数的num和这一步,可以进行优化处理,使用线段树求区间域值,时间复杂度是logn,所以总体复杂度就降到了nlogn。
4)线段树的图如下:
附:这道题也可以使用归并排序的方法。
五、代码
#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_NUM = 110000;
struct Node
{
int lChild, rChild;
int num;
}segTree[MAX_NUM*3];
void Build(int lChild, int rChild, int i)
{
segTree[i].lChild = lChild;
segTree[i].rChild = rChild;
segTree[i].num = 0;
if(lChild == rChild)return;
int mid = (lChild + rChild) >> 1;
Build(lChild, mid, i << 1);
Build(mid + 1, rChild, i + i + 1);
}
void update(int t, int o)
{
if(segTree[o].lChild == segTree[o].rChild && segTree[o].lChild == t)
{
segTree[o].num++;
return;
}
int mid = (segTree[o].lChild + segTree[o].rChild) >> 1;
if(t > mid) update(t, o + o +1);
else update(t, o + o);
segTree[o].num = segTree[o+o].num + segTree[o + o + 1].num;
}
int query(int lChild, int rChild, int i)
{
if(segTree[i].lChild == lChild && segTree[i].rChild == rChild)
return segTree[i].num;
int mid = (segTree[i].lChild + segTree[i].rChild) >> 1;
if(rChild <= mid) return query(lChild, rChild, i + i);
else if(lChild > mid) return query(lChild, rChild, i + i + 1);
else return query(lChild, mid, i * 2) + query(mid+1, rChild, i * 2 + 1);
}
int main()
{
int num;
while(cin >> num)
{
int dataArray[MAX_NUM];
int inputData;
for(int i = 0; i < num; i++)
{
cin >> inputData;
dataArray[i] = inputData;
}
Build(1, num, 1);
long long result = 0;
for(int i = 0; i < num; i++)
{
result += query(dataArray[i], num, 1);
update(dataArray[i], 1);
}
cout << result << endl;
}
return 0;
}
<Sicily>Inversion Number(线段树求逆序数)的更多相关文章
- [HDU] 1394 Minimum Inversion Number [线段树求逆序数]
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU_1394_Minimum Inversion Number_线段树求逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu1394--Minimum Inversion Number(线段树求逆序数,纯为练习)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- HDU-1394 Minimum Inversion Number(线段树求逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- 线段树求逆序数方法 HDU1394&&POJ2299
为什么线段树能够求逆序数? 给一个简单的序列 9 5 3 他的逆序数是3 首先要求一个逆序数有两种方式:能够从头開始往后找比当前元素小的值,也能够从后往前找比当前元素大的值,有几个逆序数就是几. 线段 ...
- hdu 1394 (线段树求逆序数)
<题目链接> 题意描述: 给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找 ...
- HDU - 1394 Minimum Inversion Number (线段树求逆序数)
Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs ( ...
- hdu1394 Minimum Inversion Number (线段树求逆序数&&思维)
题目传送门 Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- 【线段树求逆序数】【HDU1394】Minimum Inversion Number
题目大意: 随机给你全排列中的一个,但不断的把第一个数丢到最后去,重复N次,形成了N个排列,问你这N个排列中逆序数最小为多少 做法: 逆序数裸的是N^2 利用线段树可以降到NlogN 具体方法是插入一 ...
随机推荐
- Linux防火墙限制指定port仅仅能由指定IP訪问
须要对redis的端口做限制,仅仅能让公司内指定IP的机器訪问 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A ...
- UnrealEngine4初始化流程
自古以来全部的游戏引擎都分为三个大阶段:Init,Loop,Exit.UE4也不例外. 首先找到带有入口函数的文件:Runtime/Launch/Private/XXXX/LaunchXXXX.cpp ...
- [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)
题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...
- chrome的全局搜索快捷键
常用 文件内搜索 ctrl+f 使用快捷键 ctrl+shift+f, 就会进入到全局搜索模式 打开文件:ctrl+o 打开DevTools 你可以通过以下任何一种方式来访问DevTools: 打开浏 ...
- PSSecurityException之PowerShell权限设置
Windows下PowerShell默认的权限级别是Restricted,不允许执行PS脚本(即.ps1文件).如果在Restricted权限级别下运行,会得到错误信息: .\XXXX.ps1 : F ...
- python 3.x 学习笔记10 (析构函数and继承)
1.类变量的用途:大家公用的属性,节省开销(内存) 2.析构函数 在实例释放和销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库链接和打开的临时文件 3.私有方法两个下划线开头,声明该方法为私 ...
- HDU 3584 Cube 【 三维树状数组 】
题意:还是那篇论文里面讲到的,三维树状数组http://wenku.baidu.com/view/1e51750abb68a98271fefaa8画个立方体出来对照一下好想一点 #include< ...
- RocketMQ学习笔记(9)----RocketMQ的Producer 顺序消息
1. 顺序消息原理图 2. 什么是顺序消息? 消费消息的顺序要求同发送消息的顺序一致,在RocketMQ中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,并且发送给到 ...
- 优动漫PAINT-凌霄花画法
再见小清新~这次教程教授的是凌霄花的画法!话说这个作者的花卉系列都很米粒啊~配色什么的,赞到没话说~ 教程是简单,呃.... 没有优动漫PAINT软件肿么办? 别着急,╭(╯^╰)╮ 小编给你送来了 ...
- git远程仓库变更
查看自己的远程仓库 git remote -v 远程仓库变更 git remote remove origin //移出现有的远程仓库的地址 git remote add origin http:// ...