二维树状数组模板(区间修改+区间查询)

二维树状数组模板(区间修改+区间查询)

例题:JOIOI上帝造题的七分钟
一共两种操作:

\(L\ x_1\ y_1\ x_2\ y_2\ d\):把\((x_1,y_1)\),\((x_2,y_2)\)这个矩形内所有元素加\(d\)。
\(k\ x_1\ y_1\ x_2\ y_2\):查询\((x_1,y_1)\),\((x_2,y_2)\)这个矩形内所有元素的和。

代码如下:

#include<bits/stdc++.h>
#define RG register
#define IL inline
#define _ 2050
#define ll long long
//#define ll int
using namespace std;

ll n , m , c1[_][_],c2[_][_],c3[_][_],c4[_][_] ;

IL void upt(ll x , ll y , ll dt){
    for(RG int i = x; i <= n; i += (i & -i) )
        for(RG ll j = y; j <= m; j += (j & -j)){
            c1[ i ][ j ] += dt ;
            c2[ i ][ j ] += dt * y;
            c3[ i ][ j ] += dt * x;
            c4[ i ][ j ] += dt * x * y;
        }
}
IL ll calc(ll x,ll y){
    RG ll res = 0;
    for(RG ll i = x; i > 0; i -= (i & -i))
        for(RG ll j = y; j > 0; j -= (j & -j)){
            res = res
                + (x + 1) * (y + 1) * c1[ i ][ j ]
                - (x + 1) * c2[ i ][ j ]
                - (y + 1) * c3[ i ][ j ]
                + c4[ i ][ j ] ;
        }
    return res;
}

IL void add(ll X1,ll Y1,ll X2,ll Y2,ll dt){
    upt(X1 , Y1 , dt ) ;
    upt(X2 + 1 , Y1 , -dt ) ;
    upt(X1 , Y2 + 1, -dt ) ;
    upt(X2 + 1, Y2 + 1, dt ) ;
}
IL ll query(ll X1,ll Y1,ll X2,ll Y2){
    return
        calc(X2 , Y2) + calc(X1 - 1, Y1 - 1) -
        calc(X1 - 1 , Y2) - calc(X2 , Y1 - 1) ;
}

int main(){
    ll X1 , X2 , Y1 , Y2 , z; char c[3];
    scanf("X %lld %lld",&n,&m);
    while(scanf("%s",c)!=EOF){
        scanf("%lld%lld%lld%lld", &X1, &Y1, &X2, &Y2);
        if(c[0]=='L'){
            scanf("%lld", &z);
            add(X1 , Y1 , X2 , Y2 , z);
        }
        else printf("%lld\n",query(X1 , Y1 , X2 , Y2 ));
    }return 0;return 0;

}

原文地址:https://www.cnblogs.com/Guess2/p/8459568.html

时间: 2024-10-05 04:24:31

二维树状数组模板(区间修改+区间查询)的相关文章

二维树状数组的区间加减及查询 tyvj 1716 上帝造题的七分钟

具体解释见小结.http://blog.csdn.net/zmx354/article/details/31740985 #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack>

poj 1195 二维树状数组 及二维树状数组模板

http://poj.org/problem?id=1195 求矩阵和的时候,下标弄错WA了一次... 求矩形(x1,y1) (x2,y2)的sum |sum=sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1) 二维树状数组讲解:http://blog.csdn.net/u011026968/article/details/38532117 二维树状数组模板: /*========================================

树状数组实现区间修改+区间查询

事实上,这只是我弱弱的luogu博客的存档-- 线段树模板(1) 题意要求:给定一个序列,支持区间修改和区间查询. 智障数据结构模板题-- 当然,题目名字告诉我们要用线段树.但是线段树很长,容易出现问题,而且跑得稍慢,所以就有dalao开始yy:可不可以让树状数组支持区间修改和查询呢? 于是伟大的"超级树状数组"横空出世了. 首先,我们看树状数组是如何支持区间修改的: 设 tree[i]=a[i]-a[i-1] (差分),那么容易得到: tree[1]+tree[2]+--+tree[

二维树状数组模板

完全版 1 #include <cstdio> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int lowbit(int x) 7 { 8 return x&(-x); 9 } 10 struct tree_arr 11 { 12 int c[1005]; 13 tree_arr() 14 { 15 clear();

【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不同的矩形,并计算它们的并的大小.JYY想知道,交的大小的期望是多少.换句话说即求在所有可能的选择中,两个矩形交的面积的平均大小是多大. 输入 输入一行包含一个正整数N. 接下来N行,每行4个整数,分别为Xi,Yi,Ai,Bi 2 < =  N < =  2*10^5, 0 < =  Xi,

二维树状数组-POJ-2155-Matrix

Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 23707 Accepted: 8762 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <=

一维 + 二维树状数组 + 单点更新 + 区间更新 详解

树状数组详解: 假设一维数组为A[i](i=1,2,...n),则与它对应的树状数组C[i](i=1,2,...n)是这样定义的: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 + A4 C5 = A5 C6 = A5 + A6 ................. C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 ................ 如图可知: 为奇数的时候他是代表他本身,而为偶数的时候则是代表着自

POJ1195(二维树状数组)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 17176   Accepted: 7920 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

【二维树状数组】【CF10D】 LCIS

传送门 Description 给你两个串,求他们的最长公共上升子序列 Input 第一行是第一个串的长度\(n\) 第二行\(n\)个数代表第一个串 第三行是第二个串的长度\(m\) 第四行\(m\)个数代表第二个串 Output 输出最长子序列的长度以及方案 Hint \(For~All:\) \(0~\leq~n~\leq~500\) Solutoin 先考虑朴素DP,可以设\(f_{i,j}\)代表第一个串选前\(i\)个,第二个串选前\(j\)个的答案,转移显然\(f_{i,j}=\m