算是会把基本线段树的操作会了,不过,线段树操作非常灵活,线段树只是一个结构,它并没有存什么信息,它主要是节点保存了区间的信息。在这个节点中。
可以任意添加一些信息,这要根据不同题目而定了,所以线段树比树状数组适应的范围更广,不过在操作上看,树状数组比线段树要简单的多,而且效率比线段树要好。
所以,如果题目能用树状数组就尽量用树状数组。
这题怎么说呢,我会写线段树,也不会用。不明白啊!现在贴在这里,要仔细体会。
#include<stdio.h>
#define M 5555
int num[M<<2],a[M];
int mid;
inline void PushUp(int i){
num[i]=num[i<<1]+num[i<<1|1];
}
void build(int l,int r,int i){
num[i]=0;
if(l==r) return;
mid=(l+r)>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
PushUp(i);
}
inline void Update(int p,int l,int r,int i){
if(l==r){
num[i]++;
return;
}
mid=(l+r)>>1;
if(p<=mid) Update(p,l,mid,i<<1);
else Update(p,mid+1,r,i<<1|1);
PushUp(i);
}
inline int query(int L,int R,int l,int r,int i){
if(L<=l&&r<=R){
return num[i];
}
mid=(l+r)>>1;
int ret=0;
if(L<=mid) ret+=query(L,R,l,mid,i<<1);
if(R>mid) ret+=query(L,R,mid+1,r,i<<1|1);
return ret;
}
int main(){
int i,n,sum;
while(~scanf("%d",&n)){
sum=0;
build(0,n-1,1);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=query(a[i],n-1,0,n-1,1);
Update(a[i],0,n-1,1);
}
int ans=sum;
for(i=0;i<n;i++){
sum+=n-a[i]-a[i]-1;
if(sum<ans) ans=sum;
}
printf("%d\n",ans);
}
return 0;
}