c题晚了一分钟交就不再多写
i题 Inverse Pair
比赛的时候不会归并排序减小复杂度,补个归并排序的板子
void merge_sort(int start,int end){
if(start>=end){
return;
}
int start1=start,end1=(start+end)/2,start2=end1+1,end2=end;
merge_sort(start1,end1);
merge_sort(start2,end2);
int k=start;
while(start1<=end1&&start2<=end2){
arr[k++]=a[start1]<a[start2]?a[start1++]:a[start2++];
}
while(start1<=end1){
arr[k++]=a[start1++];
}
while(start2<=end2){
arr[k++]=a[start2++];
}
for(int i=start;i<=end;i++){
a[i]=arr[i];
}
}
此题就是对于数列中当前的x,如果存在值x+1在它之前则将它加一,得出数列利用归并排序得出逆序对数
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+7;
int n,ans;
int a[N],arr[N];
map<int,int> mp;
void merge_sort(int start,int end){
if(start>=end){
return;
}
int start1=start,end1=(start+end)/2,start2=end1+1,end2=end;
merge_sort(start1,end1);
merge_sort(start2,end2);
int k=start;
int p=start2;
while(start1<=end1&&start2<=end2){
if(a[start1]>a[start2])ans+=p-start1;
arr[k++]=a[start1]<=a[start2]?a[start1++]:a[start2++];
}
while(start1<=end1){
arr[k++]=a[start1++];
}
while(start2<=end2){
arr[k++]=a[start2++];
}
for(int i=start;i<=end;i++){
a[i]=arr[i];
}
}
signed main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1){
a[i]++;
continue;
};
if(a[i]==n){
mp[a[i]]++;
continue;
}
if(mp[a[i]+1]>0)a[i]++;
mp[a[i]]++;
}
merge_sort(1,n);
printf("%lld\n",ans);
return 0;
}