hdu - 4911 - Inversion(离散化+树状数组)

题意:一个由n个非负整数组成的序列,问进行最多k次相邻交换后最少的逆序对数 (1 ≤ n ≤ 10^5, 0 ≤ k ≤ 10^9, 0 ≤ ai ≤ 10^9)。。

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

——>>每次只能交换相邻的两个数,每次交换,只改变这两个数的逆序,其他的数对于这两个数的逆序没有改变,所以,求出所有的逆序对,再减去k就是答案。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 100000 + 10;

int n, k;
int a[MAXN], b[MAXN];
long long C[MAXN];

void Init()
{
    memset(C, 0, sizeof(C));
}

void Read()
{
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", a + i);
    }
}

int Lowbit(int x)
{
    return x & (-x);
}

long long Sum(int x)
{
    long long nRet = 0;

    while (x > 0)
    {
        nRet += C[x];
        x -= Lowbit(x);
    }

    return nRet;
}

void Add(int x)
{
    while (x <= n)
    {
        C[x]++;
        x += Lowbit(x);
    }
}

void Solve()
{
    int nCnt = 0;
    int nId = 0;
    long long nReverse = 0;

    memcpy(b, a, sizeof(a));
    sort(b, b + n);
    nCnt = unique(b, b + n) - b;

    for (int i = n - 1; i >= 0; --i)
    {
        nId = lower_bound(b, b + nCnt, a[i]) - b + 1;
        nReverse += Sum(nId - 1);
        Add(nId);
    }

    if (nReverse > k)
    {
        nReverse -= k;
    }
    else
    {
        nReverse = 0;
    }

    printf("%I64d\n", nReverse);
}

int main()
{
    while (scanf("%d%d", &n, &k) == 2)
    {
        Init();
        Read();
        Solve();
    }
    return 0;
}
时间: 2024-10-12 11:01:42

hdu - 4911 - Inversion(离散化+树状数组)的相关文章

HDU 5101 Select --离散化+树状数组

题意:n 组,每组有一些值,求 在不同的两组中每组选一个使值的和大于k的方法数. 解法:n * Cnt[n] <= 1000*100 = 100000, 即最多10^5个人,所以枚举每个值x,求他的后面那些组中有多少数大于 k-x即可, 求有多少数大于k-x可以先求有多少数小于等于k-x,然后总数减一下即可. 可以用树状数组求. 先把所有数离散地存入一个树状数组中,然后每次枚举完一组的数后,将这组的数去掉. 代码: #include <iostream> #include <cst

HDU 5862(离散化+树状数组)

Problem Counting Intersections 题目大意 给定n条水平或竖直的线段,统计所有线段的交点个数. (n<=100000) 解题分析 首先将线段离散化. 然后将所有线段按照横坐标的顺序,按照先插入再查找再删除的顺序进行操作. 对于横线 如果是左端点,则将其纵坐标加1,右端点则减1,对于竖线直接求和就行了. 参考程序 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include

hdu 3015 Disharmony Trees (离散化+树状数组)

Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663    Accepted Submission(s): 307 Problem Description One day Sophia finds a very big square. There are n trees in the square. T

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

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

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

hdu 2227(dp+树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1466    Accepted Submission(s): 521 Problem Description

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

poj 2299 Ultra-QuickSort 离散化 + 树状数组

题目链接:http://poj.org/problem?id=2299 离散化 + 树状数组 教科书例题般的题目 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <vector> #include <stack> #include <set> #include

HDU 1541 Stars (树状数组)

Problem Description Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given

CodeForces 540E - Infinite Inversions(离散化+树状数组)

花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树状数组,但是发现那些没有交换的数也会产生逆序对数,但我没有算. 经明神提示, 把没有用到的数字段化成点.然后用树状数组算一下就好了. 然后我用一个数组记录每个点的长度.比如 <1,2><5,6>,1,2,3,4,5,6只有1,2,5,6用到了,那么离散化为1,2,3,4,5,f[1]=