一、题目描述

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)线段树的图如下:

附:这道题也可以使用归并排序的方法。

五、代码

  1. #include<iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int MAX_NUM = 110000;
  7. struct Node
  8. {
  9. int lChild, rChild;
  10. int num;
  11. }segTree[MAX_NUM*3];
  12. void Build(int lChild, int rChild, int i)
  13. {
  14. segTree[i].lChild = lChild;
  15. segTree[i].rChild = rChild;
  16. segTree[i].num = 0;
  17. if(lChild == rChild)return;
  18. int mid = (lChild + rChild) >> 1;
  19. Build(lChild, mid, i << 1);
  20. Build(mid + 1, rChild, i + i + 1);
  21. }
  22. void update(int t, int o)
  23. {
  24. if(segTree[o].lChild == segTree[o].rChild && segTree[o].lChild == t)
  25. {
  26. segTree[o].num++;
  27. return;
  28. }
  29. int mid = (segTree[o].lChild + segTree[o].rChild) >> 1;
  30. if(t > mid) update(t, o + o +1);
  31. else update(t, o + o);
  32. segTree[o].num = segTree[o+o].num + segTree[o + o + 1].num;
  33. }
  34. int query(int lChild, int rChild, int i)
  35. {
  36. if(segTree[i].lChild == lChild && segTree[i].rChild == rChild)
  37. return segTree[i].num;
  38. int mid = (segTree[i].lChild + segTree[i].rChild) >> 1;
  39. if(rChild <= mid) return query(lChild, rChild, i + i);
  40. else if(lChild > mid) return query(lChild, rChild, i + i + 1);
  41. else return query(lChild, mid, i * 2) + query(mid+1, rChild, i * 2 + 1);
  42. }
  43. int main()
  44. {
  45. int num;
  46. while(cin >> num)
  47. {
  48. int dataArray[MAX_NUM];
  49. int inputData;
  50. for(int i = 0; i < num; i++)
  51. {
  52. cin >> inputData;
  53. dataArray[i] = inputData;
  54. }
  55. Build(1, num, 1);
  56. long long result = 0;
  57. for(int i = 0; i < num; i++)
  58. {
  59. result += query(dataArray[i], num, 1);
  60. update(dataArray[i], 1);
  61. }
  62. cout << result << endl;
  63. }
  64. return 0;
  65. }

<Sicily>Inversion Number(线段树求逆序数)的更多相关文章

  1. [HDU] 1394 Minimum Inversion Number [线段树求逆序数]

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

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

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

  3. hdu1394--Minimum Inversion Number(线段树求逆序数,纯为练习)

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. dll开发

    _declspec(dllexport) void fun() { }

  2. Codeforces 701E Connecting Universities 贪心

    链接 Codeforces 701E Connecting Universities 题意 n个点的树,给你2*K个点,分成K对,使得两两之间的距离和最大 思路 贪心,思路挺巧妙的.首先dfs一遍记录 ...

  3. 线程进阶:多任务处理(17)——Java中的锁(Unsafe基础)

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  4. C# 实现ADSL自动断网和拨号(适用于拨号用户)

    using System;using System.Runtime.InteropServices; public struct RASCONN{    public int dwSize;    p ...

  5. Django shortcut functions

    django.shortcuts package提供提供帮助类和函数可以更便捷的操作MVC中的每一部分,包含: render(request, template_name,[dictionary],[ ...

  6. 读 Real-Time Rendering 收获 - chapter 4. transform

    chapter 4. Transform p54 affine transform p57 all rotation matrices have a determinant of one and ar ...

  7. activity的23张表

    --二进制数据表 SELECT * FROM act_ge_bytearray; --属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录, SELECT * FROM act_g ...

  8. watch监听

    watch: { getTitle:{ handler:function(val,oldval){ }, deep:true//对象内部的属性监听,也叫深度监听 }, },

  9. BZOJ 5104 Fib数列(二次剩余+BSGS)

    斐波那契数列的通项: \[\frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})-(\frac{1-\sqrt{5}}{2}))\] 设T=\(\sqrt{5}*N\),\ ...

  10. luogu P1592 互质(欧拉函数)

    题意 (n<=106,k<=108) 题解 一开始以为是搜索. 但想想不对,翻了一眼题解发现是欧拉函数. 因为 gcd(a,b)=gcd(a,a+b) 所以和n互质的数应该是类似a1,a2 ...