您的位置:首页 > 其它

hdu 4911 Inversion (多校第5场,求逆序数对,离散化)

2014-08-06 10:06 423 查看
题目大意:

求给定数组的逆序数对。最后答案如果比k小,输出0,否则输出ans-k。

我用树状数组求逆序数对。二分查找离散化,因为a的范围太大,10^9 数组开不下。

开始没有用__int64 wa T^T

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL __int64
LL a[111111];
LL b[111111];
LL binarySeach(LL x,int l,int r)
{
int m=(l+r)>>1;
int ret=m;
while(l<=r)
{
if(b[m]>=x)
{
ret=m;
r=m-1;
}else l=m+1;
m=(l+r)>>1;
}
return ret + 1;
}
LL c[111111];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int n)
{
while(x<=n)
{
c[x]++;
x+=lowbit(x);
}
}
LL query(int x)
{
LL an=0;
while(x>=1)
{
an+=c[x];
x-=lowbit(x);
}
return an;
}
int main()
{
int n,k,i,j;
while(scanf("%d%d",&n,&k)==2)
{
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
j=0;
for(i=1;i<n;i++)
{
if(b[i]==b[j])continue;
j++;
b[j]=b[i];
}
int all = j;
for(i=0;i<n;i++)
{
a[i]=binarySeach(a[i],0,all);
}
LL ans=0;
memset(c,0,sizeof(c));
for(i=n-1;i>=0;i--)
{
ans+=query(a[i]-1);
add(a[i],n);
}
ans-=k;
if(ans<0)ans =0;
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息