转自 https://www.cnblogs.com/zwfymqz/p/7788554.html#_label1
Vector两行代码求逆序对
首先我们想一下冒泡排序的过程,我们不难发现,对于每一个元素,我们实际上是让他不停的和前面的元素比较,交换。
也正是因为这个过程决定了在冒泡排序的过程中:一个位置的数的前面的数一定是递增的(从小到大排的话)
那么我们在交换的时候,直接二分找到一个合适的位置,插入即可
这个很显然可以用平衡树Vector实现
代码也非常短,
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,ans,a[100001];
vector<int>v;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
int now=upper_bound(v.begin(),v.end(),a[i])-v.begin();
ans=ans+i-now-1,v.insert(v.begin()+now,a[i]);
}
printf("%d",ans);
return 0;
}
Vector六行代码过平衡树
洛谷P3369
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>v;
int n,opt,x;
int main()
{
v.reserve(100001);
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&opt,&x);
if(opt==1) v.insert(lower_bound(v.begin(),v.end(),x),x);
if(opt==2) v.erase (lower_bound(v.begin(),v.end(),x));
if(opt==3) printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
if(opt==4) printf("%d\n",v[x-1]);
if(opt==5) printf("%d\n",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]);
if(opt==6) printf("%d\n",v[upper_bound(v.begin(),v.end(),x)-v.begin()]);
}
return 0;
}