入门树状数组(左边比x小的个数)

来源:互联网 发布:使命召唤ol流畅优化 编辑:程序博客网 时间:2024/04/27 15:46

我们在这里求第i个数左边有几个比它小的数,还有右边有几个比它小的数。
那左边的这一种情况来说吧,在这里设置一个数组 C[]吧,先从a[i]向左扫描,让C[k]=1,表示大小为K 的值已经被扫描到了,所以他左边比它小的个数就C[1]+C[2]++++++C[a[i]-1],也就是是sum[a[i]]。然后向上更新点C[a[i]]++。


//左边比他小的数的 个数 //试下1 2 3 4 5  #if 0#include<iostream>#include<cstring>using namespace std;const int MAXX=10000;int a[MAXX];int c[MAXX];int S_L[MAXX];int S_R[MAXX];int max_a;int lowbit(int x){return x&(-x);}void add(int x,int v){for(; x<=max_a; x+=lowbit(x))c[x]+=v;}int sum(int x){int sum=0;for(; x>0; x-=lowbit(x)){sum+=c[x];}return sum;}int main(){int n;    max_a=0;cin>>n;for(int i=1; i<=n; i++){cin>>a[i];max_a=max(max_a,a[i]);}for(int i=1; i<=n; i++){S_L[i]=sum(a[i]);add(a[i],1);}memset(c,0,sizeof(c));            //把数反过来  就是右边小的数的个数  for(int i=n; i>=1; i--){S_R[i]=sum(a[i]);add(a[i],1); }cout<<"the number of minner at left: "<<endl;for(int i=1; i<=n; i++)cout<<S_L[i]<<" ";cout<<endl;cout<<"the number of minner at right: "<<endl;for(int i=1; i<=n; i++)cout<<S_R[i]<<" ";cout<<endl;}#endif 

阅读全文
0 0