题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911

解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少是多少?

因为每次相邻的交换操作最多只能减少一个逆序对,所以最多可以减少k个逆序对,所以我们只要求出原来的序列有多少个逆序对然后减去k再跟0取较大的就可以了。

因为数据范围是10的五次方,所以暴力求肯定会TLE,所以要用n*logn算法求逆序对,n*logn算法有几种可以求逆序对的:

线段树,树状数组,归并排序。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef __int64 INT;
const int maxn = +; struct node
{
int d,cixu;
}A[maxn];
struct Node
{
int l,r;
INT n;
}tree[*maxn];
bool cmp1(node a,node b)
{
if(a.d == b.d) return a.cixu < b.cixu;
return a.d < b.d;
}
bool cmp2(node a,node b)
{
return a.cixu < b.cixu;
}
void build(int p)
{
if(tree[p].l == tree[p].r) return ;
int mid = (tree[p].l + tree[p].r) / ;
tree[*p].l = tree[p].l;
tree[*p].r = mid;
tree[*p].n = tree[*p+].n = ;
tree[*p+].l = mid + ;
tree[*p+].r = tree[p].r;
build(*p);
build(*p+);
}
void insert(int p,int l)
{
tree[p].n++;
if(tree[p].l == tree[p].r) return ;
int mid = (tree[p].l + tree[p].r) / ;
if(l <= mid) insert(*p,l);
else insert(*p+,l);
}
INT query(int p,int l,int r)
{
if(l > r) return ;
if(tree[p].l == l && tree[p].r == r)
return tree[p].n;
int mid = (tree[p].l + tree[p].r) / ;
if(r <= mid) query(*p,l,r);
else if(l <= mid && r > mid)
return query(*p,l,mid) + query(*p+,mid+,r);
else return query(*p+,l,r);
} int main()
{
int n;
INT k;
while(scanf("%d%I64d",&n,&k)!=EOF)
{
tree[].l = ;
tree[].r = n;
tree[].n = ;
build();
for(int i = ;i <= n;++i)
{
scanf("%d",&A[i].d);
A[i].cixu = i;
}
sort(A+,A+n+,cmp1);
int f = ,hehe = 0x7fffffff;
for(int i = ;i <= n;++i)
{
if(A[i].d != hehe)
{
hehe = A[i].d;
f++;
}
A[i].d = f;
}
sort(A+,A+n+,cmp2);
INT ans = ;
for(int i = ;i <= n;++i)
{
ans += query(,A[i].d+,n);
insert(,A[i].d);
}
ans = ans-k > ? (ans-k) : ;
printf("%I64d\n",ans);
}
return ;
}

HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)的更多相关文章

  1. HDU 1394 Minimum Inversion Number(线段树求逆序对)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1394 解题报告:给出一个序列,求出这个序列的逆序数,然后依次将第一个数移动到最后一位,求在这个过程中 ...

  2. HDU 1394 线段树求逆序对

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

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

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

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

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

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

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

  6. hdu 1394 Minimum Inversion Number 【线段树求逆序数】

    之前写过树状数组的,再用线段树写一下--- #include<cstdio> #include<cstring> #include<iostream> #inclu ...

  7. hdu 6318 Swaps and Inversions (线段树求逆序对数)

    Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. HDU - 1394 Minimum Inversion Number(线段树求逆序数---点修改)

    题意:给定一个序列,求分别将前m个数移到序列最后所得到的序列中,最小的逆序数. 分析:m范围为1~n,可得n个序列,求n个序列中最小的逆序数. 1.将序列从头到尾扫一遍,用query求每个数字之前有多 ...

  9. hdu 4911 求逆序对数+树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=4911 给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 实际上每交换一次能且只能 ...

随机推荐

  1. 怎样开发单页面app

    groot.view("myview", function (vm, ve) { ve.loada = function () { require("./app/page ...

  2. 让C#开发更简单,抽象增删改

    相信经常做一些MS,CRM 项目的童鞋非常有体会,大部分时间都是在复制和粘贴,大部分项目框架都是建一个三层,首先是DAL建一些增删改查,然后呢是BLL业务层再建一些增删改查,然后UI层再调用增删改查, ...

  3. php检测php.ini是否配制正确

    运行命令行 php -d display_startup_errors=1 -d error_reporting=-1 -d display_errors -c "C:\path-to-ph ...

  4. apply与call

    看这个apply真正应用.bind这是一个绑定时间的函数 var bind=function(object,type,fn){ if(object.attachEvent){//IE浏览器 objec ...

  5. js中的DOM操作(2)

    1.表格的更加与删除 <!DOCTYPE html> <html> <head> <title>表格操作</title> <style ...

  6. setter方法的内存错误

    - (void)setList:(ClassicList *)list { self.list = list; _titleLabel.text = list.activityName; _addre ...

  7. 寒假 OC-代理,类目,内存,协议,延展,数组,字典,集合

     OC04字符串博客:1.http://www.cnblogs.com/heyonggang/p/3452556.html (字符串常用方法)2.http://blog.sina.com.cn/s/b ...

  8. openvpn的介绍和搭建过程

    本文摘自:http://www.linuxidc.com/Linux/2012-01/51702.htm,在这只是为了做个笔记使用

  9. localStorage和sessionStorage的区别

    //在chrome测试的结果; 知识点1:localStorage和sessionStorage的区别; localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除local ...

  10. Java-TreeSet

    如下: package 集合类.Set类; /** * Set不允许重复数据 */ /** * TreeSet 是用来进行集合排序的,请注意他和LinkedHashSet的区别. TreeSet是按照 ...