题意:给你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; }
时间: 2024-10-29 03:19:53