HDU4911-Inversion(树状数组)

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 914    Accepted Submission(s): 380

Problem Description

bobo has a sequence a1,a2,…,an. He is allowed to swap two adjacent numbers for no more than k times.

Find the minimum number of inversions after his swaps.

Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.

Input

The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).

Output

For each tests:

A single integer denotes the minimum number of inversions.

Sample Input

3 1
2 2 1
3 0
2 2 1

Sample Output

1
2

题意:n个数,最多有k次相邻位置的数的交换,问最小的逆序数为多少

思路:保证每次交换逆序数都减小,可以参考冒泡排序的做法。最后只要计算原数列逆序数,然后减掉k即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
const int maxn = 100000+10;
int sum[maxn];
int n,k;
int num[maxn],tn[maxn];
map<int,int> mma;
bool cmp(int a,int b){
    return a > b;
}
int lowbit(int x){
    return x&(-x);
}
void add(int x,int d){
    while(x < maxn){
        sum[x] += d;
        x += lowbit(x);
    }
}
int getS(int x){
    int ret = 0;
    while(x > 0){
        ret += sum[x];
        x -= lowbit(x);
    }
    return ret;
}
int main(){

    while(~scanf("%d%d",&n,&k)){
        mma.clear();
        memset(sum,0,sizeof sum);
        for(int i = 1; i <= n; i++){
            scanf("%d",&num[i]);
            tn[i] = num[i];
        }
        sort(tn+1,tn+n+1,cmp);
        int i = 1,cnt = 1;
        while(i <= n){
            mma[tn[i]] = cnt;
            int j = i+1;
            while(j <= n && tn[i]==tn[j]){
                j++;
            }
            cnt++;
            i = j;
        }
        long long ret = 0;
        for(int i = 1; i <= n; i++){
            ret += getS(mma[num[i]]-1);
            add(mma[num[i]],1);
        }
        long long  ans = ret-k;
        if(ans < 0) ans = 0;
        cout<<ans<<endl;
    }
    return 0;
}

HDU4911-Inversion(树状数组),布布扣,bubuko.com

时间: 2024-08-09 11:03:43

HDU4911-Inversion(树状数组)的相关文章

hdoj 4911 Inversion 树状数组+离散化

题意:给你n个可以重复的无序数列,问经过k次相邻交换后最少还有多少对逆序数 求逆序对可以用树状数组来做,对于重复的元素,可能在sort的时候交换编号 求和的时候要注意去重,还有一种方法就是稳定排序stable_sort #include<string.h> #include<stdio.h> #include<algorithm> using namespace std; #define ll __int64 #define N 100000+10 struct ln{

HDU 4911 Inversion 树状数组求逆序数对

显然每次交换都能降低1 所以求出逆序数对数,然后-=k就好了.. . _(:зゝ∠)_ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<set> #include<map> #include<iostream> #include<algorithm> using namespace std; #define N 100005 #define

[hdu1394]Minimum Inversion Number(树状数组)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18395    Accepted Submission(s): 11168 Problem Description The inversion number of a given number sequence a1, a2, ..., a

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

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13942    Accepted Submission(s): 8514 Problem Description The inversion number of a given number sequence a1, a2, ..., a

hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数)

题目链接 题意: 给一个n个数的序列a1, a2, ..., an ,这些数的范围是0-n-1, 可以把前面m个数移动到后面去,形成新序列:a1, a2, ..., an-1, an (where m = 0 - the initial seqence)a2, a3, ..., an, a1 (where m = 1)a3, a4, ..., an, a1, a2 (where m = 2)...an, a1, a2, ..., an-1 (where m = n-1)求这些序列中,逆序数最少的

hdu-5497 Inversion(滑动窗口+树状数组)

题目链接: Inversion Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1087    Accepted Submission(s): 323 Problem Description You have a sequence {a1,a2,...,an} and you can delete a contiguous subsequ

Hdu 1394 Minimum Inversion Number(线段树或树状数组)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 11981    Accepted Submission(s): 7321 Problem Description The inversion number of a given number sequence a1, a2, ..., a

Inversion (hdu 4911 树状数组 || 归并排序 求逆序对)

Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 2003    Accepted Submission(s): 787 Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two adjacent numbers fo

HDU 1394 Minimum Inversion Number 树状数组&amp;&amp;线段树

题目给了你一串序列,然后每次 把最后一个数提到最前面来,直到原来的第一个数到了最后一个,每次操作都会产生一个新的序列,这个序列具有一个逆序数的值,问最小的你逆序数的值为多少 逆序数么 最好想到的是树状数组,敲了一把很快,注意把握把最后一个数提上来对逆序数的影响即可, #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #i

UVA 11990 `Dynamic&#39;&#39; Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3141 题意 一个1到n的排列,每次随机删除一个,问删除前的逆序数 思路 综合考虑,对每个数点,令value为值,pos为位置,time为出现时间(总时间-消失时间),明显是统计value1 > value2, pos1 < pos2, time1 < time2的个