POJ 1195 Mobile phones

来源:互联网 发布:雅士尼处理器软件 编辑:程序博客网 时间:2024/06/04 18:28

树状数组第一题,上来就是二维树状数组,这是逼着我用树状数组做啊,二维线段树不会写啊~~


题目大意:

给定矩阵大小,可以更新矩阵中的某些数,要求输出某个范围内的所有数之和。


解题思路:

二维树状数组可解。

一维树状数组讲解:点击打开。

二维树状数组只是在更新方式上稍作改变。

在数组长度为n的树状数组中:

寻找下一个需要添加的数的下标:

int lowbit(int x){    return x&(-x);}


一维树状数组更新是这样的:

void add(int x,int val){    for(;x<=n;x+=lowbit(x))    {        num[x]+=val;    }}

二维树状数组更新是这样的:

void  add(int x,int y,int val){    for(int i=x;i<=s;i+=lowbit(i))    {        for(int j=y;j<=s;j+=lowbit(j))        {            num[i][j]+=val;        }    }}


一维树状数组查询是这样的:

int query(int x){    int ans=0;    for(;x>0;x-=lowbit(x))    {        ans+=c[i];    }    return ans;}

查询的是1到x的数总和。


二维树状数组查询是这样的

int query(int x,int y){    int ans=0;    for(int i=x;i>0;i-=lowbit(i))    {        for(int j=y;j>0;j-=lowbit(j))        {            ans+=num[i][j];        }    }    return ans;}

查询的是(1,1)到(x,y)的数的总和。


下面是代码:

#include <stdio.h>#include <string.h>int num[1050][1050],s;int lowbit(int x){    return x&(-x);}void  add(int x,int y,int val){    for(int i=x;i<=s;i+=lowbit(i))    {        for(int j=y;j<=s;j+=lowbit(j))        {            num[i][j]+=val;        }    }}int query(int x,int y){    int ans=0;    for(int i=x;i>0;i-=lowbit(i))    {        for(int j=y;j>0;j-=lowbit(j))        {            ans+=num[i][j];        }    }    return ans;}int main(){    int t,q,x,y,sum,l,r,a;    scanf("%d%d",&t,&s);    memset(num,0,sizeof(num));    while(scanf("%d",&q),q<3)    {        if(q==1)        {            scanf("%d%d%d",&x,&y,&a);            x++;            y++;            add(x,y,a);        }        else if(q==2)        {            scanf("%d%d%d%d",&x,&y,&l,&r);            x++;            y++;            l++;            r++;            printf("%d\n",query(l,r)-query(l,y-1)-query(x-1,r)+query(x-1,y-1));        }    }    return 0;}



0 0
原创粉丝点击