这道题很明显是求逆序对。

所谓逆序对,就是逆序的数对。

譬如在下面这个数列中:

1 2 3 4 6 5

6 5就是一个逆序对。


求逆序对的方法比较多,常见的有归并排序和树状数组(线段树当然也行)。

本题采用平衡树(leafy tree)解决。(之所以写这个才不是因为我懒呢!)

对于数列中的每一项,插入,然后查询它的rank。

累加即为答案。

写的时候因为直接黏贴模板被坑了好几次(尴尬至极),大概告诉我两件事:

  1. 这题得开long long

  2. 不注释文件输入可能不是RE而是TLE

速度很慢,效率很低,2212ms。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const long long N=500500;
namespace LeafyTree{
const long long alpha=4;
long long n,cnt,father,root;
long long val[N<<2],size[N<<2],ls[N<<2],rs[N<<2];
inline void newNode(long long &pos,long long v){
pos=++cnt,size[pos]=1,val[pos]=v;
}
inline void copyNode(long long x,long long y){
size[x]=size[y],ls[x]=ls[y],rs[x]=rs[y],val[x]=val[y];
}
void merge(long long l,long long r){
size[++cnt]=size[l]+size[r],val[cnt]=val[r],ls[cnt]=l,rs[cnt]=r;
}
void rotate(long long pos,bool flag){
if(flag){
merge(ls[pos],ls[rs[pos]]);
ls[pos]=cnt,rs[pos]=rs[rs[pos]];
}else{
merge(rs[ls[pos]],rs[pos]);
rs[pos]=cnt,ls[pos]=ls[ls[pos]];
}
}
void maintain(long long pos){
if(size[ls[pos]]>size[rs[pos]]*alpha)rotate(pos,0);
else if(size[rs[pos]]>size[ls[pos]]*alpha)rotate(pos,1);
if(size[ls[pos]]>size[rs[pos]]*alpha)rotate(ls[pos],1),rotate(pos,0);
else if(size[rs[pos]]>size[ls[pos]]*alpha)rotate(rs[pos],0),rotate(pos,1);
}
void pushup(long long pos){
if(!size[ls[pos]])return;
size[pos]=size[ls[pos]]+size[rs[pos]];
val[pos]=val[rs[pos]];
}
void insert(long long pos,long long v){
if(size[pos]==1){
newNode(ls[pos],min(v,val[pos]));
newNode(rs[pos],max(v,val[pos]));
pushup(pos);
return;
}
if(v>val[ls[pos]])insert(rs[pos],v);
else insert(ls[pos],v);
pushup(pos);
maintain(pos);
}
void erase(long long pos,long long v){
if(size[pos]==1){
if(ls[father]==pos)copyNode(father,rs[father]);
else copyNode(father,ls[father]);
return;
}
father=pos;
if(v>val[ls[pos]])erase(rs[pos],v);
else erase(ls[pos],v);
pushup(pos);
maintain(pos);
}
long long kth(long long pos,long long v){
if(size[pos]==v)return val[pos];
if(v>size[ls[pos]])return kth(rs[pos],v-size[ls[pos]]);
return kth(ls[pos],v);
}
long long rank(long long pos,long long v){
if(size[pos]==1)return 1;
if(v>val[ls[pos]])return rank(rs[pos],v)+size[ls[pos]];
return rank(ls[pos],v);
}
}
using namespace LeafyTree;
namespace Solve{
template<typename T>inline void read(T &x){
x=0;T f=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write(T x){
if(x>=10)write(x/10);
putchar(x%10+'0');
}
const long long INF=9223372036854775807;
long long n,ans;
long long a[N];
inline void solve(){
read(n);
newNode(root,INF);
for(register long long i=1;i<=n;++i){
read(a[i]),insert(root,a[i]);
ans+=i-rank(root,a[i]+1)+1;
}
write(ans);
}
}
using namespace Solve;
int main(){
// freopen("testdata.in","r",stdin);
solve();
}

最新文章

  1. postgres 正则表达式 转
  2. 配置OpenCV产生flann\logger.h(66): error C4996: &#39;fopen&#39;: This function or variable may be unsafe问题[zz]
  3. C#的数组
  4. 慕课编程题JS选项卡切换
  5. zookeeper 相关学习资料
  6. ORA-02287: 此处不允许序号
  7. Git – Fast Forward 和 no fast foward
  8. 测试api代码,简单的接口测试代码
  9. beta阶段事后诸葛亮会议
  10. 非对称SVD电影推荐系统
  11. js不验证
  12. hdu2025java字符题
  13. 自理一遍android 高级知识
  14. 九、VueJs 填坑日记之在项目中使用jQuery
  15. 从Java到JVM到OS线程睡眠
  16. log4net:ERROR ConfigureFromXml called with null &#39;element&#39; parameter
  17. POI (Apache POI)
  18. 无责任共享 Coursera、Udacity 等课程视频(转载)
  19. Java—集合框架详解
  20. iOS开发swift语法0基础篇—————(swift技术交流群:361513739)

热门文章

  1. C#中的文本乱码问题
  2. C#中的public protected internal private
  3. Ruby中使用patch HTTP方法
  4. 【简单的案例分享,停机10分钟】10204升级CRS&amp;amp;DB的PSU至102044
  5. mysql改动用户password
  6. LCA 近期公共祖先 小结
  7. 2014.08.04,读书,读书笔记-《Matlab概率与数理统计分析》-第1章 MATLAB的数据基础
  8. Word技巧杂记(二)——批量修改修订格式并接受
  9. Hello The World! —— 致我们无悔的IT之旅
  10. hdoj--1028--Ignatius and the Princess III(母函数)