ACM 逆序对 hdu 4911 Inversion 离散化 树状数组模板

来源:互联网 发布:ubuntu安装atom 编辑:程序博客网 时间:2024/05/15 00:41

ACM 逆序对 

简单可证明,每一次移动都可以减少一个逆序对,因此

设逆序对个数为sum,这答案为sum-k,如sum-k<0则直接输出0即可

先排序离散化,然后逆序对使用树状数组求。


Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 244    Accepted Submission(s): 102


Problem Description
bobo has a sequence a1,a2,…,an. He is allowed to swap twoadjacent 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 12 2 13 02 2 1
 

Sample Output
12
 

Author
Xiaoxu Guo (ftiasch)

Accepted1001250MS2332KG++

#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;#define out(x) cout<<#x<<": "<<x<<endlconst double eps(1e-8);const int maxn=101000;const long long maxint=-1u>>1;const long long maxlong=maxint*maxint;typedef long long lint;struct wjj{    int x,y;};int n,k,b[maxn],big;long long f[maxn];wjj a[maxn];long long sum;void init(){    for (int i=1; i<=n; i++)     {        scanf("%d",&a[i].x);        a[i].y=i;    }}bool cmp(wjj a,wjj b){    return (a.x<b.x || (a.x==b.x && a.y<b.y));}int lowb(int x){    return x&(-x);}long long find(int x){    long long tmp = 0;    int y = x;    while (y>0){        tmp += f[y];        y -= lowb(y);    }    return tmp;}void insert(int x){    int y = x;    while (y<=n){        f[y] ++;        y += lowb(y);    }}void work(){    big=0;    sort(a+1,a+1+n,cmp);    a[0].x=-1;    for (int i=1; i<=n; i++)    {        if (a[i].x!=a[i-1].x) big++;        b[a[i].y]=big;    }    memset(f,0,sizeof(f));    long long ans = 0;    for (int i = 1; i <= n; i ++){        ans +=  (find(n)-find(b[i]));        insert(b[i]);    }    if (ans<=k) cout<<0<<endl;    else cout<<ans-k<<endl;}int main(){    while(cin>>n>>k)    {        init();        work();    }    return 0;}





0 0
原创粉丝点击