【模板】二维线段树or树状数组(poj-1195)

Problem

Poj

题意:给定二维平面,维护单点加与区间求和操作

Solution

蒟蒻最近开始学数据结构了,发现了二维结构这种神奇的东东

这题不过就是二维树状数组或线段树的裸题,发这篇博客不过是为了贴个板子

Code

二维树状数组

#include<cstdio>
#include<cstring>
using namespace std;
#define lowbit(x) (-x&x)
const int maxn=1050;
int n,f[maxn][maxn];

inline void add(int x,int y,int add){
    for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=n;j+=lowbit(j))f[i][j]+=add;   
    return ;
}

inline int query(int x,int y){
    int sum=0;
    for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j))sum+=f[i][j];
    return sum;
}

int main(){
    int p;
    int a,b,c;
    int l,xia,r,shang;
    while(1){
        scanf("%d",&p);
        if(!p){scanf("%d",&n);memset(f,0,sizeof(f));continue;}
        else if(p==1){scanf("%d%d%d",&a,&b,&c);add(a+1,b+1,c);continue;}
        else if(p==2){scanf("%d%d%d%d",&l,&xia,&r,&shang);l++,r++,xia++,shang++;printf("%d\n",query(r,shang)+query(l-1,xia-1)-query(l-1,shang)-query(r,xia-1));continue;}
        else if(p==3)return 0;
    }
    return 0;
}

二维线段树

#include<cstdio>
#include<cctype>
using namespace std;
typedef long long ll;
#define rg register
#define cl(x) memset(x,0,sizeof(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>0?(x):(-(x)))

template <typename _Tp> inline _Tp read(_Tp&x){
    rg char c11=getchar(),ob=0;x=0;
    while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
    while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}

const int N=1010;
int seg[N<<2][N<<2],n;

#define mid (((l)+(r))>>1)

inline void add2(int x,int l,int r,int xx,int Y,int Z){
    seg[x][xx]+=Z;
    if(l==r)return ;
    if(Y<=mid)add2(x,l,mid,xx<<1,Y,Z);
    else add2(x,mid+1,r,xx<<1|1,Y,Z);
    return ;
}

inline void add1(int l,int r,int x,int X,int Y,int Z){
    add2(x,1,n,1,Y,Z);
    if(l==r)return ;
    if(X<=mid)add1(l,mid,x<<1,X,Y,Z);
    else add1(mid+1,r,x<<1|1,X,Y,Z);
    return ;
}

inline int sum2(int x,int l,int r,int xx,int B,int T){
    if(B<=l&&r<=T)return seg[x][xx];
    int tmp(0);
    if(B<=mid)tmp+=sum2(x,l,mid,xx<<1,B,T);
    if(mid<T)tmp+=sum2(x,mid+1,r,xx<<1|1,B,T);
    return tmp;
}

inline int sum1(int l,int r,int x,int L,int R,int B,int T){
    if(L<=l&&r<=R)return sum2(x,1,n,1,B,T);
    int tmp(0);
    if(L<=mid)tmp+=sum1(l,mid,x<<1,L,R,B,T);
    if(mid<R)tmp+=sum1(mid+1,r,x<<1|1,L,R,B,T);
    return tmp;
}

int main(){
    int opt,x,y,z,l,r,b,t;
    while(1){
        read(opt);
        switch(opt){
            case 0:read(n);break;
            case 1:read(x),read(y),read(z);add1(1,n,1,x+1,y+1,z);break;
            case 2:read(l),read(b),read(r),read(t);printf("%d\n",sum1(1,n,1,l+1,r+1,b+1,t+1));break;
            case 3:return 0;
            default : puts("ERROR"); return 0;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40515553/article/details/79921119
今日推荐