P4514 上帝造题的七分钟——二维树状数组

P4514 上帝造题的七分钟

求的是矩阵里所有数的和;

维护四个树状数组;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2050;
int b[maxn][maxn],bi[maxn][maxn],bj[maxn][maxn],bij[maxn][maxn];
char s[2];
int n,m,num;

void add(int x,int y,int z) {for(int i=x;i<=n;i+=i&(-i)) for(int j=y;j<=m;j+=j&(-j)) b[i][j]+=z;}
void addi(int x,int y,int z) {for(int i=x;i<=n;i+=i&(-i)) for(int j=y;j<=m;j+=j&(-j)) bi[i][j]+=z;}
void addj(int x,int y,int z) {for(int i=x;i<=n;i+=i&(-i)) for(int j=y;j<=m;j+=j&(-j)) bj[i][j]+=z;}
void addij(int x,int y,int z) {for(int i=x;i<=n;i+=i&(-i)) for(int j=y;j<=m;j+=j&(-j)) bij[i][j]+=z;}

int query_(int x,int y) { int ans=0; for(int i=x;i;i-=i&(-i)) for(int j=y;j;j-=j&(-j)) ans+=b[i][j]; return ans;}
int query_i(int x,int y) { int ans=0; for(int i=x;i;i-=i&(-i)) for(int j=y;j;j-=j&(-j)) ans+=bi[i][j]; return ans;}
int query_j(int x,int y) { int ans=0; for(int i=x;i;i-=i&(-i)) for(int j=y;j;j-=j&(-j)) ans+=bj[i][j]; return ans;}
int query_ij(int x,int y) { int ans=0; for(int i=x;i;i-=i&(-i)) for(int j=y;j;j-=j&(-j)) ans+=bij[i][j]; return ans;}

void add_all(int x,int y,int num)
{
    add(x,y,num);
    addi(x,y,num*x);
    addj(x,y,num*y);
    addij(x,y,num*x*y);
}

int query(int x,int y)
{
    int ans=0;
    ans+=query_(x,y)*(x*y+x+y+1)-query_i(x,y)*(y+1)-query_j(x,y)*(x+1)+query_ij(x,y);
    return ans;
}

int main()
{
    scanf("%s%d%d",s,&n,&m);
    while(~scanf("%s",s))
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(s[0]==‘L‘)
        {
            scanf("%d",&num);
            add_all(x1,y1,num);
            add_all(x1,y2+1,-num);
            add_all(x2+1,y1,-num);
            add_all(x2+1,y2+1,num);
        }
        else
        {
            printf("%d\n",query(x2,y2)-query(x2,y1-1)-query(x1-1,y2)+query(x1-1,y1-1));
        }

    }

    return 0;
}

我写的比较丑了,也可以将加入和查询操作放在结构体里面;

struct node
{
    int tree[2050][2050];

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

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

    int query(int x,int y)
    {
        int res=0;
        for(int i=x; i>=1; i-=lowbit(i))
            for(int j=y; j>=1; j-=lowbit(j))
                res+=tree[i][j];
        return res;
    }
}b,bi,bj,bij;

差分和前缀和的思想;

原文地址:https://www.cnblogs.com/WHFF521/p/11675222.html

时间: 2024-10-10 09:19:28

P4514 上帝造题的七分钟——二维树状数组的相关文章

tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着身体. 描述 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵.第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作.第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作.第

BZOJ 3132: 上帝造题的七分钟( 二维BIT )

二维树状数组... 自己YY一下再推一下应该可以搞出来... ---------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

二维树状数组的区间加减及查询 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>

bzoj3132 上帝造题的七分钟(差分+二维树状数组)

bzoj3132 上帝造题的七分钟(差分+二维树状数组) Time Limit: 20 Sec Memory Limit: 128 MB Description "第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. 第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作. 第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围. 第五分

二维树状数组(水题) POJ1195

前段时间遇到线段树过不了,树状数组却过了的题.(其实线段树过得了的) 回忆了下树状数组. 主要原理,还是二进制位数,每一项的和表示其为它的前((最后一位1及其后)的二进制数)和,可从二进制图来看.(用线段树想一想其实只是线段树编号不同而已,本质类似) 写了下二维树状数组,几乎和一维相同,也没必要不同. #include <cstdio> #include <cstring> int l,r,x,y,n,a,p,sum[1125][1125]; inline int lowbit(i

POJ2155/LNSYOJ113 Matrix【二维树状数组+差分】【做题报告】

这道题是一个二维树状数组,思路十分神奇,其实还是挺水的 题目描述 给定一个N∗NN∗N的矩阵AA,其中矩阵中的元素只有0或者1,其中A[i,j]A[i,j]表示矩阵的第i行和第j列(1≤i,j≤N)(1≤i,j≤N),初始矩阵元素都是0.在矩阵上进行TT次操作,操作有以下两种: (1)格式为C x1 y1 x2 y2(1≤x1≤x2≤n,1≤y1≤y2≤n)C x1 y1 x2 y2(1≤x1≤x2≤n,1≤y1≤y2≤n) ,其中CC为字符“C”,表示把以(x1,y1)(x1,y1)为左上角,

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

二维树状数组模板(区间修改+区间查询) 例题: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 i

POJ1195 Mobile phones 【二维树状数组】

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

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