您的位置:首页 > 理论基础 > 数据结构算法

ACM常用模板——数据结构——树状数组

2015-11-17 15:45 375 查看
(一)
一维BIT求和
模型:求区间[l,r]的和

#define maxn 10005

using namespace std;

int n,bit[maxn];

int sum(int i)//前i项的和

{

int s=0;

while(i>0)s+=bit[i],i-=i&-i;

return s;

}

void add(int i,int x)//第i项增加x,更新bit数组

{

while(i<=n){bit[i]+=x;i+=i&-i;}

}

int main()

{

int i,x,s,e,m;

while(~scanf("%d%d",&n,&m)){

memset(bit,0,sizeof(bit));

for(i=1;i<=n;i++){

scanf("%d",&x);

add(i,x);

}

while(m--){

scanf("%d%d",&s,&e);

printf("%d\n",sum(e)-sum(s-1));

}

}

}

[/code]

(二)树状数组求逆序数

#define maxn 10005

using namespace std;

int n,bit[maxn],a[maxn];

int sum(int i)//前i项的和

{

int s=0;

while(i>0)s+=bit[i],i-=i&-i;

return s;

}

void add(int i,int x)//第i项增加x,更新bit数组

{

while(i<=n){bit[i]+=x;i+=i&-i;}

}

int solve()//求逆序数个数

{

int ans=0,i;

for(i=0;i<n;i++){

ans+=i-sum(a[i]);

add(a[i],1);

}

return ans;

}

int main()

{

int i;

while(~scanf("%d",&n)){

memset(bit,0,sizeof(bit));

    for(i=0;i<n;i++){

scanf("%d",&a[i]);

}

printf("%d\n",solve());

}

}

[/code]

(三)二维树状数组

模型:矩阵初始化为0,C x1 y1 x2 y2:把矩阵翻转(0变1,,1变0),Q x y:查询位置x y的值

const int MAXN = 1010;

int c[MAXN][MAXN];

int n;

int sum(int x,int y)

{

int ret = 0;

for(int i = x;i > 0;i -= i&(-i))

for(int j = y;j > 0;j -= j&(-j))

ret += c[i][j];

return ret;

}

void add(int x,int y,int val)

{

for(int i = x;i <= n;i += i&(-i))

for(int j = y;j <= n;j += j&(-j))

c[i][j] += val;

}


int main()

{

int T;

scanf("%d",&T);

while(T--)

{

int q;

scanf("%d%d",&n,&q);

memset(c,0,sizeof(c));

char op[10];

int x1,y1,x2,y2;

while(q--)

    {

scanf("%s",op);

if(op[0] == 'C')

{

scanf("%d%d%d%d",&x1,&y1,&x2,&y2);

add(x1,y1,1);

add(x2+1,y1,1);

add(x1,y2+1,1);

add(x2+1,y2+1,1);

}

else

{

scanf("%d%d",&x1,&y1);

if(sum(x1,y1)%2 == 0)printf("0\n");

    else printf("1\n");

}

}

if(T > 0)printf("\n");

}

return 0;

}


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: