题意:给定一个序列,求分别将前m个数移到序列最后所得到的序列中,最小的逆序数。

分析:m范围为1~n,可得n个序列,求n个序列中最小的逆序数。

1、将序列从头到尾扫一遍,用query求每个数字之前有多少个大于该数字的数,方法如下。

(1)将已经扫过的数字所对应的位置标记,通过query求该数字之后有多少个数被标记过

(2)该数字之后所有被标记的数字,都是在该数字之前出现过的(i<j),而这些数字又大于该数字(ai>aj),因此该数字之后所有的标记和就是该数字之前比该数字大的数的个数。

2、sum为初始序列的逆序和,从前往后依次将每个数字移到序列最后。

假设当前把a[i]移到序列最后,则

后一个序列B的逆序和=前一个序列A的逆序和 - a[i] + (n - 1 - a[i])。

eg:假设前一个序列A为3 6 9 0 8 5 7 4 2 1,则a[i]为3。

a[i]是序列A的第一个数,a[i]后面的数中有a[i]个数小于a[i](分别为0,2,1),因此把a[i]移到最后,会减少a[i]个逆序数。

而a[i]后面的数中有 (n - 1 - a[i])个数大于a[i],因此把a[i]移到最后,会增加 (n - 1 - a[i])个逆序数。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 5000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int a[MAXN];
int cnt[MAXN << 2];
void update(int k, int id, int L, int R){
if(L == R){
++cnt[id];
}
else{
int mid = L + (R - L) / 2;
if(k <= mid) update(k, id << 1, L, mid);
else update(k, id << 1 | 1, mid + 1, R);
cnt[id] = cnt[id << 1] + cnt[id << 1 | 1];
}
}
int query(int l, int r, int id, int L, int R){
if(l <= L && R <= r){
return cnt[id];
}
int mid = L + (R - L) / 2;
int ans = 0;
if(l <= mid) ans += query(l, r, id << 1, L, mid);
if(r > mid) ans += query(l, r, id << 1 | 1, mid + 1, R);
return ans;
}
int main(){
int n;
while(scanf("%d", &n) == 1){
memset(cnt, 0, sizeof cnt);
int sum = 0;
for(int i = 0; i < n; ++i){
scanf("%d", &a[i]);
sum += query(a[i] + 1, n, 1, 1, n);
update(a[i] + 1, 1, 1, n);
}
int ans = sum;
for(int i = 0; i < n; ++i){
sum = sum - a[i] + (n - 1 - a[i]);
ans = min(ans, sum);
}
printf("%d\n", ans);
}
return 0;
}

 

HDU - 1394 Minimum 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 (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  3. hdu - 1394 Minimum Inversion Number(线段树水题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...

  4. HDU 1394 Minimum Inversion Number 线段树

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...

  5. HDU 1394 Minimum Inversion Number(线段树 或 树状数组)

    题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...

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

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

  7. hdu 13394 Minimum Inversion Number 线段树

    题意: 首先给你一个长度为n的序列v,你需要首先找出来逆序对(i<j && v[i]>v[j]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...

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

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

  9. HDU 1394 Minimum Inversion Number (树状数组)

    题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...

  10. HDU 1394 Minimum Inversion Number(树状数组/归并排序实现

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

随机推荐

  1. run jumper server

    1. 生成key: $ if [ "$SECRET_KEY" = "" ]; then SECRET_KEY=`cat /dev/urandom | tr -d ...

  2. webservice之实现天气预报

    前通过传智的视频自学了webservice的基本使用,也了解到webservice就是一种跨编程语言和跨操作系统平台的远程调用技术. 对于这些理论知识在这里也不再做过多的解释,本次主要就是记录与分享使 ...

  3. nodejs中this详解

    最近在用Nodejs进行APP运维服务管理系统开发时发现,nodejs中的this经常会变,查了下资料后发现this在不同的代码位置中代表不同的涵义,在实际运用过程中可以用var self = thi ...

  4. python如何画三维图像?

    python三维图像输出的代码如下所示:#画3D函数图像输出from mpl_toolkits.mplot3d import Axes3Dfrom matplotlib import cmimport ...

  5. 小程序PromiseAll定义

    var promiseAll = (funcs, callback) =>{ var promises = [] for(var i=0; i<funcs.length; i++){ pr ...

  6. D - Beautiful Graph (深搜)

    这个题深搜容易解决,结果用了广搜,动手之前还是要想清楚,然后自己的代码写错的情况下,没有重写,而是在原有的基础上,进行修改,结果有个判定的初始化条件放错位置,浪费了一个小时... 就是给一个无向图,任 ...

  7. java SHA1加密算法

    package com.cn.test.rsa; import java.security.MessageDigest; import java.security.NoSuchAlgorithmExc ...

  8. 十三、$.ajax、模态/非模态框、window.open()、href属性、submit()等提交请求优劣及问题解决方法

    1. $.ajax提交请求进行数据更新,并通过回调进行有效提示 function updateAudit(dispacher, control) { var currentpage = documen ...

  9. MVC5仓库管理系统

    下载

  10. python列表元组 魔法方法

    1.元祖 count()    统计某个字符串的出现次数 tuple.count('22')    返回一个整数 index()    获取某个值出现的位置 2.列表 字符串可以直接转换列表    l ...