题意:给你n个可以重复的无序数列,问经过k次相邻交换后最少还有多少对逆序数
求逆序对可以用树状数组来做,对于重复的元素,可能在sort的时候交换编号
求和的时候要注意去重,还有一种方法就是稳定排序stable_sort
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll __int64
#define N 100000+10
struct ln{
int id,va;
}in[N];
int a[N],c[N];
int n;
int cmp(ln x,ln y)
{
return x.va<y.va;
}
int lowbit(int x) { return x&(-x);}
void updata(int t,int value)
{
for(int i=t;i<=n;i+=lowbit(i))
c[i]+=value;
}
int getSum(int x)
{
int temp=0;
for(int i=x;i>=1;i-=lowbit(i))
temp+=c[i];
return temp;
}
int main()
{
int k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&in[i].va);
in[i].id=i;
}
memset(c,0,sizeof(c));
sort(in+1,in+n+1,cmp);
a[in[1].id]=1;
for(int i=2;i<=n;i++)
{
if(in[i].va!=in[i-1].va)
a[in[i].id]=i;
else
a[in[i].id]=a[in[i-1].id];
}
ll ans=0;
for(int i=1;i<=n;i++)
{
updata(a[i],1);
printf("%d %d\n",getSum(a[i]),getSum(a[i]-1));
int temp=i-getSum(a[i]-1);
temp=temp-(getSum(a[i])-getSum(a[i]-1));
ans+=temp;
}
if(ans-k<0) printf("0\n");
else
printf("%I64d\n",ans-k);
}
return 0;
}
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll __int64
#define N 100000+10
struct ln{
int id,va;
}in[N];
int a[N],c[N];
int n;
int cmp(ln x,ln y)
{
return x.va<y.va;
}
int lowbit(int x) { return x&(-x);}
void updata(int t,int value)
{
for(int i=t;i<=n;i+=lowbit(i))
c[i]+=value;
}
int getSum(int x)
{
int temp=0;
for(int i=x;i>=1;i-=lowbit(i))
temp+=c[i];
return temp;
}
int main()
{
int k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&in[i].va);
in[i].id=i;
}
memset(c,0,sizeof(c));
stable_sort(in+1,in+n+1,cmp);
for(int i=1;i<=n;i++)
a[in[i].id]=i;
ll ans=0;
for(int i=1;i<=n;i++)
{
updata(a[i],1);
int temp=i-getSum(a[i]);
ans+=temp;
}
if(ans-k<0) printf("0\n");
else
printf("%I64d\n",ans-k);
}
return 0;
}