您的位置:首页 > 其它

洛谷1908 逆序对 权值线段树模板

2018-03-20 22:01 381 查看
题目:逆序对

参考:
dalao的题解    <-这位大佬写的好清晰的orz
dalao讲的权值线段树

思路:归并的题,但是可以用权值线段树做。

注意:权值线段树就是以权值为下标的线段树,由于权值可能很大,所以要先离散化。

代码:#include <bits/stdc++.h>
using namespace std;

#define maxn 40000

struct Pair {
int x, y;
Pair(int xx=-1,int yy=-1) {
x=xx,y=yy;
}
bool operator < (const Pair& oth) const {
return y<oth.y||(y==oth.y&&x<oth.x);
}
};

int n,m=0;
Pair a[maxn+5];
int c[maxn+5];
int tr[maxn*4+5]={0};
int p,q=m+1;

void update(int o,int l,int r) {
if(l>p||r<p) return ;
if(l==r) {
tr[o]++;
return ;
}
int lc=o*2,rc=o*2+1,mid=l+(r-l)/2;
update(lc,l,mid),update(rc,mid+1,r);
tr[o]=tr[lc]+tr[rc];
}

int query (int o,int l,int r) {
if(l>m+1||r<p) return 0;
if(l>=p&&r<=m+1) {
return tr[o];
}
int lc=o*2,rc=o*2+1,mid=l+(r-l)/2;
return query(lc,l,mid)+query(rc,mid+1,r);
}

int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i].y);
a[i].x=i;
}
sort(a+1,a+n+1);
for(int i=1; i<=n; i++) {
if(a[i].y!=a[i-1].y) m++;
c[a[i].x]=m;
}
int ans=0;
for(int i=1;i<=n;i++){
p=c[i];
int s=query(1,1,m+1);
ans+=s;
update(1,1,m+1);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息