树状数组的个人总结

来源:互联网 发布:阿里云的钱怎么提现 编辑:程序博客网 时间:2024/05/29 13:35

模板组成

 

模板构成

Lowbit (x)//返回x的最低位1

Eg:2^0 2^1 2^2

Updata(int x,int val)//更新数据

{

while(x<=n)//更新的时候我们要更新包含a[x]的所有c[x];

//查找父节点的时候我们就需要lowbit()

    {

        c[x]+=val;

        x+=lowbit(x);

    }

}

 

如果我们在a[6]数组加val

我们需要更新c[6]

Lowbit6=2

继续更新c[6+lowbit[6]]+=val;

6+lowbit[6]=8;

Lowbit[8]=8;

继续更新c[8+8]+=val;

Getsumint n//求和运算

{

Int sum=0;

While(n>0)

{sum+=c[n];

n-=lowbit[n];

}

}

这里的求和数据和上一个更新数据相反

这里是不断 往下寻找

 

Sum[9]=c[9]+c[9-lowbit[9]]c[8]+(c[0]   因为0不满足条件就跳出)

因为lowbit(9)=2^0-=1

lowbit(8)=2^3-=8

 

 

 

主要的思路是这个实际的应用需要通过练习

For example

求逆序数

输入n

然后输入n个数据

Input

5

1  3  2  5  4

Output

2

分析

每个数据具有两个属性num(数值)pos(位置)

Struct data

{

Int num,pos;

}

输入

For(int i=1;i<=n;i++)

{scanf(“%d”.&a[i].num);

A[i].pos=i;

}

Sort(a,a+n,cmp)//将数据进行排序num从小到大

//注意数值相同时按照pos排序

离散一下空间

定义hash10003】;

For(int i=1;i<=n;i++)

{

Hash[a[i].pos]=i;

}

Int sum=0;

For(int i=1;i<=n;i++)

{

Updata(hash[i],1);

Sum+=hash[i];

}

Print(“%d\n”,sum);

 

 

0 0
原创粉丝点击