<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 具体方法是插入一 ... 
随机推荐
- 使用XMLHttpRequest解析json
			不适用内函数或者promise的方式,可以在外部提取到json数据 <!DOCTYPE html> <html lang="en"> <head> ... 
- Testbench代码设计技巧
			Testbench代码设计技巧 " There are many ways " to code a test case, it all depens on the creativi ... 
- zzuoj--10401--物资调度(dfs)
			A.物资调度 Time Limit: 2 Sec Memory Limit: 128 MB Submit: 93 Solved: 52 [Submit][Status][Web Board] De ... 
- ORACLE 索引批量重建
			按用户批量重建索引: 按用户将此用户下面非临时表上面的索引全部重建,此过程建议在SYS用户下面执行: CREATE OR REPLACE PROCEDURE BATCH_REBUILD_INDEX(U ... 
- SPSS学习小记
			2013年1月8日 最近一直在SPSS中处理数据,涉及到函数部分,不是太懂,特记录于此,以便翻阅. SPSS判断字符变量中是否含有某字符串的表示方式: (INDEX(url,'ad')>0 ... 
- WPF学习(四) - 附加属性
			冷静了一晚,我就当这次学习的过程是在看狗血剧情的武打小说吧:没有垃圾的武术,只有垃圾的武者…… 还有个话儿怎么说来着:你们是用户,不是客户,也就有个使用的权力.搞清楚身份,别叽叽歪歪的! 没办法,全世 ... 
- JS循环 for while 全局/局部变量 短路
			循环语句: For for循环的格式 for(var i = 0; i < 10; i ++){ } for循环的执行顺序: ① ② 若判断为 true 进④ 进③ 进②判断 ……循环 ... 
- 用canvas画一个的小画板(PC端移动端都能用)
			前言 本篇的内容主要包括: canvas标签简介 画板的功能简介 画板的JS部分(包括:1.获取画布 2.使画板全屏幕显示且自适应 3.如何绘制直线 4.绘画时的三种状态(鼠标点击.移动.离开)5.画 ... 
- P3369 【模板】普通平衡树(Treap/SBT)(pb_ds版)
			题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(若有多个相同的数,因输出最小的排名) 查询 ... 
- 读 Real-Time Rendering 收获 - chapter 6. texturing
			Texturing, at its simplest, is a techinique for efficiently modeling the surface's properties. 
