hdu4911Inversion 树状数组求逆序对

来源:互联网 发布:win7网络位置类型设置 编辑:程序博客网 时间:2024/06/11 04:18
//给一个序列 , 可以进行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;    }} 

0 0
原创粉丝点击