您的位置:首页 > 其它

hdu4911Inversion 树状数组求逆序对

2015-09-02 19:17 393 查看
//给一个序列 , 可以进行k次相邻元素的交换 , 问
//问交换后的序列最少有多少个逆序对
//很好想到没经过一次相邻的元素的交换 , 逆序对的个数都会剪一
//答案直接就是原来的序列的个数-k就行
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std ;
const int maxn = 1e5+10 ;
typedef long long ll ;
int tree[maxn] ;
int a[maxn] ;
int b[maxn] ;
int getsum(int x)
{
    int sum = 0 ;
    while(x)
    {
        sum += tree[x] ;
        x -= x&(-x) ;
    }
    return sum ;
}
void update(int x , int dx)
{
    while(x < maxn)
    {
        tree[x] += dx ;
        x += (x)&(-x) ;
    }
}
int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    int n , k ;
    while(~scanf("%d%d" , &n , &k))
    {
        memset(tree , 0 , sizeof(tree)) ;
        for(int i = 1;i <= n;i++)
        scanf("%d" , &a[i]) , b[i] = a[i] ;
        sort(b+1 , b+1+n) ;
        int len = unique(b+1 , b+1+n) - (b+1) ;
        ll ans = 0 ;
        for(int i = 1;i <= n;i++)
        {
            int pos = lower_bound(b+1 , b+1+len , a[i]) - b ;
            update(pos , 1) ;
            ans += (i - getsum(pos)) ;
        }
        if(ans < k)
        puts("0") ;
        else cout<<(ans-k)<<endl;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: