飞!

题解

首先,求逆序数对的思路:
1.得到整个数列后,从前往后扫,统计比a[i]小的,在a[i]后面的有多少个
这样做的话,应该是只有n2的暴力作法,没想到更好的方法
2.统计a[i]前面的,且比它大的数
这样做的话,就可以利用输入的时效性,每输入一个数,就把这个数的num[i]值加1,
然后统计比这个数大的数的num和,
因为这里的和一定是在这个数列中比a[i]大,且在它前面出现的数之和,
然后把把这个和加到总逆序数sum里。
这样做的话直接的暴力作法依然是n2,但是,
我们可以在,统计比这个数大的数的num和这一步进行优化,利用线段树求区间域值的复杂度是logn,
所以总体复杂度就降到了nlogn。
 
再来看这道题,求得初始数列的逆序数后,再求其他排列的逆序数有一个规律,就是
sum = sum + (n - 1 - a[i]) - a[i];
这个自行验证吧,相信很容易得出
 
最后,拓展一下,如果要求正序数怎么办?很简单,无非是大小调一下
再问,如果要求满足i<j<k,且a[i]>a[j]>a[k]的数对总数怎么办?
 
可以从中间的这个数入手,统计a[i]>a[j]的对数m,以及a[j]>a[k]的对数n,m*n就是。。。
要求a[i]>a[j]的个数还是一样的,那么a[j]>a[k]的个数呢?
两种思路:
1.得到a[i]>a[j]的对数后,将数列倒过来后再求a[j]<a[k]的对数
2.更简单的做法是,找到规律发现,n = 整个数列中比a[j]小的数 — 在a[j]前面已经出现的比a[j]小的数的个数
即(假设数列是从1开始的) n = (a[j] -1) - (j - 1 - m )
 
如果不理解模拟一边就明白了。
AC代码:
#include <cstdio>

#include <algorithm>

using namespace std;

#define lson l , m , rt << 1

#define rson m + 1 , r , rt << 1 | 1

const int maxn = ;

int sum[maxn<<];

void PushUP(int rt) {

         sum[rt] = sum[rt<<] + sum[rt<<|];

}

void build(int l,int r,int rt) {

         sum[rt] = ;

         if (l == r) return ;

         int m = (l + r) >> ;

         build(lson);

         build(rson);

}

void update(int p,int l,int r,int rt) {

         if (l == r) {

                 sum[rt] ++;

                 return ;

         }

         int m = (l + r) >> ;

         if (p <= m) update(p , lson);

         else update(p , rson);

         PushUP(rt);

}

int query(int L,int R,int l,int r,int rt) {

         if (L <= l && r <= R) {

                 return sum[rt];

         }

         int m = (l + r) >> ;

         int ret = ;

         if (L <= m) ret += query(L , R , lson);

         if (R > m) ret += query(L , R , rson);

         return ret;

}

int x[maxn];

int main() {

         int n;

         while (~scanf("%d",&n)) {

                 build( , n -  , );

                 int sum = ;

                 for (int i =  ; i < n ; i ++) {

                          scanf("%d",&x[i]);

                          sum += query(x[i] , n -  ,  , n -  , );

                          update(x[i] ,  , n -  , );

                 }

                 int ret = sum;

                 for (int i =  ; i < n ; i ++) {

                          sum += n - x[i] - x[i] - ;

                          ret = min(ret , sum);

                 }

                 printf("%d\n",ret);

         }

         return ;

}

hdu Minimum Inversion Number(逆序数的小知识与线段树)的更多相关文章

  1. hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394  //hdu 题目   Problem Description The inversion number ...

  2. hdu 1394 Minimum Inversion Number 逆序数/树状数组

    Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showprob ...

  3. HDU-1394 Minimum Inversion Number (逆序数,线段树或树状数组)

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  4. HDU 4911 Inversion (逆序数 归并排序)

    Inversion 题目链接: http://acm.hust.edu.cn/vjudge/contest/121349#problem/A Description bobo has a sequen ...

  5. ZYB's Premutation(有逆序数输出原序列,线段树)

    ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. HDU 1394 Minimum Inversion Number(线段树的单点更新)

    点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...

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

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

  8. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  9. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

随机推荐

  1. 基于C++任意点数的FFT/IFFT(时域和频域)实现

    函数说明:更改主函数体中的N和length(=log2(N))既可以实现任意点数(2的幂次)的FFT/ IFFT的实现,fft函数中flag标志位控制是正变换还是逆变换. 1.复数操作类      定 ...

  2. mssql error 26

    右击数据库选择“方面”,将“RemoteAccessEnabled”属性设为“True”,点“确定”

  3. jetty分析

    jetty处理过程: 1  new Server() (1)初试化线程池  生成固定大小线程数,新来的线程放入BlockingQueue. (2)初始化ServerConnector 初始化 sche ...

  4. 【总结整理】JS的继承

    参考阮一峰的文章:http://javascript.ruanyifeng.com/oop/inheritance.html#toc4 function Shape() { this.x = 0; t ...

  5. GCD 学习(一)简介

    文章摘抄至:http://zhuyanfeng.com/archives/3015 并有一些改动 GCD(Grand Central Dispatch)是从OS X Snow Leopard和iOS ...

  6. EZOJ #73

    传送门 分析 我们知道如果对于模数$P$有$gcd(x,P) = 1$则$x$一定有且仅有一个逆元,可以表示为 $x \equiv \frac{y}{1} (mod P)$ 即为$xy \equiv ...

  7. spoj2142 Arranging Flowers

    传送门 题目大意 给你n和m,表示一个n*n的数独已经填完了m行,让你填出剩下几行,要求答案的字典序最小. 分析 看到这道题我首先想到的是记录每行每列使用了哪些数字,然后贪心的来填,但是发现用这种策略 ...

  8. Django框架 之 view视图

    Django框架 之 view视图 浏览目录 概述 简单的视图 HttpRequest对象 CBV和FBV 给视图加装饰器 Request对象 Response对象 JsonResponse对象 Dj ...

  9. rest-framework组件 之 分页

    分页 简单分页 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination class PNPag ...

  10. delete请求,删除不成功?

    因为,在数据库底层,其实并没有删除该数据,只是将数据的标识设置为is_deleted.因此,最后即使删除了,查询的时候还是会显示在界面. 故,需要重写get请求.