BZOJ 3132: 上帝造题的七分钟 树状数组+差分

本文介绍了一种使用二维树状数组(Binary Indexed Tree, BIT)进行区间更新与查询的巧妙算法。通过四个树状数组协同工作,可以高效地处理二维平面上的矩形区域加法更新和求和查询,特别适用于需要频繁更新和查询的场景。

这个思路很巧妙啊 ~ 

code: 

#include <cstdio> 
#include <algorithm> 
#define N 2050
#define ll int  
#define setIO(s) freopen(s".in","r",stdin)       
using namespace std; 
struct BIT { 
    ll C[N][N]; 
    int lowbit(int t) {
        return t&(-t);      
    }    
    void update(int x,int y,int d) {
        for(int i=x;i<N;i+=lowbit(i)) {
            for(int j=y;j<N;j+=lowbit(j)) {
                C[i][j]+=d; 
            }
        }
    } 
    ll query(int x,int y) { 
        ll re=0;  
        for(int i=x;i;i-=lowbit(i)) {
            for(int j=y;j;j-=lowbit(j)) {
                re+=C[i][j]; 
            }
        }
        return re; 
    }
}A,B,C,D; 
void Add(int x,int y,int d) {       
    A.update(x,y,d);    
    B.update(x,y,x*d);  
    C.update(x,y,y*d);  
    D.update(x,y,x*y*d);   
}
ll qu(int x,int y) {
    ll qa=A.query(x,y)*(x*y+x+y+1);  
    ll qb=-B.query(x,y)*(y+1);  
    ll qc=-C.query(x,y)*(x+1); 
    ll qd=D.query(x,y);   
    return qa+qb+qc+qd;  
}
int main() { 
    // setIO("input");    
    char sr[2]; 
    int i,j;     
    int n; 
    int m; 
    scanf("%s",sr); 
    scanf("%d%d",&n,&m);   
    while(scanf("%s",sr)!=EOF) { 
        int a,b,c,d,e; 
        if(sr[0]=='L') {     
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);         
            Add(a,b,e); 
            Add(a,d+1,-e); 
            Add(c+1,b,-e); 
            Add(c+1,d+1,e);       
        }
        else { 
            scanf("%d%d%d%d",&a,&b,&c,&d); 
            printf("%d\n",qu(c,d)-qu(a-1,d)-qu(c,b-1)+qu(a-1,b-1));   
        }
    }
    return 0; 
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值