poj1195二维线段树,区间求和,单点跟新

来源:互联网 发布:读写器软件 编辑:程序博客网 时间:2024/06/11 09:31

昨天搞了下二维线段树,今天来练练手~~感觉不错。

二维线段树~我这里用的是树中有树的方法,建的二维线段树。也就是x坐标一棵树。然后每个对应x坐标的区间,又有一颗树为y坐标。

理解了 也就跟一维线段树 差不多。

#include<stdio.h>#include<stdlib.h>#include<string.h>#define ll long long#define maxn 1025#define inf 0x3f3f3f3fll sum[maxn*4][maxn*4];ll s; int n;void pushup(int rt,int x){    sum[x][rt]=sum[x][rt*2]+sum[x][rt*2+1];}void buildy(int rt,int left,int right,int xrt)//y坐标{    if(left==right) sum[xrt][rt]=0;    else    {        int mid=(left+right)/2;        buildy(rt*2,left,mid,xrt);        buildy(rt*2+1,mid+1,right,xrt);        pushup(rt,xrt);    }}void build(int rt,int left,int right)//确定x坐标{    buildy(1,1,n,rt);    if(left!=right)    {        int mid=(left+right)/2;        build(rt*2,left,mid);        build(rt*2+1,mid+1,right);    }}void updatey(int rt,int left,int right,int y,int xrt,ll add){    if(left==right&&left==y)    {        sum[xrt][rt]+=add;        return ;    }    int mid=(left+right)/2;    if(y<=mid) updatey(rt*2,left,mid,y,xrt,add);    if(y>mid) updatey(rt*2+1,mid+1,right,y,xrt,add);    pushup(rt,xrt);}void update(int rt,int left,int right,int x,int y,ll add){    updatey(1,1,n,y,rt,add);    if(left!=right)    {        int mid=(left+right)/2;        if(x<=mid) update(rt*2,left,mid,x,y,add);        if(x>mid) update(rt*2+1,mid+1,right,x,y,add);    }}void queryY(int rt,int left,int right,int y1,int y2,int xrt){    if(left>=y1&&right<=y2)    {        s+=sum[xrt][rt];        return ;    }    int mid=(left+right)/2;    if(y1<=mid) queryY(rt*2,left,mid,y1,y2,xrt);    if(y2>mid) queryY(rt*2+1,mid+1,right,y1,y2,xrt);}void query(int rt,int left,int right,int x1,int y1,int x2,int y2){    if(left>=x1&&right<=x2)    {        queryY(1,1,n,y1,y2,rt);        return ;    }    int mid=(left+right)/2;    if(x1<=mid) query(rt*2,left,mid,x1,y1,x2,y2);    if(x2>mid) query(rt*2+1,mid+1,right,x1,y1,x2,y2);}int main(){    int op;    int x,y;    ll w;    int x1,y1,x2,y2;    while(scanf("%d",&op))    {        if(op==0){            scanf("%d",&n);            n++;            build(1,1,n);        }        else if(op==1)        {            scanf("%d%d%lld",&x,&y,&w);            x++,y++;            update(1,1,n,x,y,w);        }        else if(op==2)        {            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);            s=0;            x1++,y1++,x2++,y2++;            query(1,1,n,x1,y1,x2,y2);            printf("%lld\n",s);        }        else break;    }}



原创粉丝点击