震惊!Vector两行代码求逆序对,六行代码过普通平衡树
Posted 自为
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了震惊!Vector两行代码求逆序对,六行代码过普通平衡树相关的知识,希望对你有一定的参考价值。
Vector两行代码求逆序对
背景:济南集训Day7上午T2,出了一道逆序对的裸题,SB的我没看出是逆序对来,于是现场推了一个很刁钻的求逆序对的方法
首先我们想一下冒泡排序的过程,我们不难发现,对于每一个元素,我们实际上是让他不停的和前面的元素比较,交换。
也正是因为这个过程决定了在冒泡排序的过程中:一个位置的数的前面的数一定是递增的(从小到大排的话)
那么我们在交换的时候,直接二分找到一个合适的位置,插入即可
这个很显然可以用平衡树Vector实现
代码也非常短,
1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 using namespace std; 5 int n,m,ans,a[100001]; 6 vector<int>v; 7 int main() 8 { 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 11 for(int i=1;i<=n;i++) 12 { 13 int now=upper_bound(v.begin(),v.end(),a[i])-v.begin(); 14 ans=ans+i-now-1,v.insert(v.begin()+now,a[i]); 15 } 16 printf("%d",ans); 17 return 0; 18 }
Vector六行代码过平衡树
这个参考了一下黄学长的博客,不过我没有用迭代器实现
顺便精简了一下代码
代码应该比较容易懂,就不细讲了
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 vector<int>v; 6 int n,opt,x; 7 int main() 8 { 9 v.reserve(100001); 10 scanf("%d",&n); 11 while(n--) 12 { 13 scanf("%d%d",&opt,&x); 14 if(opt==1) v.insert(lower_bound(v.begin(),v.end(),x),x); 15 if(opt==2) v.erase (lower_bound(v.begin(),v.end(),x)); 16 if(opt==3) printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1); 17 if(opt==4) printf("%d\n",v[x-1]); 18 if(opt==5) printf("%d\n",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]); 19 if(opt==6) printf("%d\n",v[upper_bound(v.begin(),v.end(),x)-v.begin()]); 20 } 21 return 0; 22 }
总的来说
Vector是个好东西,
试想一下如果未来每场考试都开O2的话,
数组这个东西会不会就消失了?
以上是关于震惊!Vector两行代码求逆序对,六行代码过普通平衡树的主要内容,如果未能解决你的问题,请参考以下文章