题解 P1774 【最接近神的人_NOI导刊2010提高(02)】
2024-08-31 12:40:04
这道题很明显是求逆序对。
所谓逆序对,就是逆序的数对。
譬如在下面这个数列中:
1 2 3 4 6 5
6 5就是一个逆序对。
求逆序对的方法比较多,常见的有归并排序和树状数组(线段树当然也行)。
本题采用平衡树(leafy tree)解决。(之所以写这个才不是因为我懒呢!)
对于数列中的每一项,插入,然后查询它的rank。
累加即为答案。
写的时候因为直接黏贴模板被坑了好几次(尴尬至极),大概告诉我两件事:
这题得开long long
不注释文件输入可能不是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();
}
最新文章
- postgres 正则表达式 转
- 配置OpenCV产生flann\logger.h(66): error C4996: &#39;fopen&#39;: This function or variable may be unsafe问题[zz]
- C#的数组
- 慕课编程题JS选项卡切换
- zookeeper 相关学习资料
- ORA-02287: 此处不允许序号
- Git – Fast Forward 和 no fast foward
- 测试api代码,简单的接口测试代码
- beta阶段事后诸葛亮会议
- 非对称SVD电影推荐系统
- js不验证
- hdu2025java字符题
- 自理一遍android 高级知识
- 九、VueJs 填坑日记之在项目中使用jQuery
- 从Java到JVM到OS线程睡眠
- log4net:ERROR ConfigureFromXml called with null &#39;element&#39; parameter
- POI (Apache POI)
- 无责任共享 Coursera、Udacity 等课程视频(转载)
- Java—集合框架详解
- iOS开发swift语法0基础篇—————(swift技术交流群:361513739)
热门文章
- C#中的文本乱码问题
- C#中的public protected internal private
- Ruby中使用patch HTTP方法
- 【简单的案例分享,停机10分钟】10204升级CRS&;amp;DB的PSU至102044
- mysql改动用户password
- LCA 近期公共祖先 小结
- 2014.08.04,读书,读书笔记-《Matlab概率与数理统计分析》-第1章 MATLAB的数据基础
- Word技巧杂记(二)——批量修改修订格式并接受
- Hello The World! —— 致我们无悔的IT之旅
- hdoj--1028--Ignatius and the Princess III(母函数)