P4514 上帝造题的七分钟

题目背景

裸体就意味着身体。

题目描述

“第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵。

第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作。

第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作。

第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围。

第五分钟,和雪说,要有耐心,于是便有了时间限制。

第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中及最终结果均不超过32位有符号整数类型的表示范围的限制。

第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。”

——《上帝造裸题的七分钟》

所以这个神圣的任务就交给你了。

输入输出格式

输入格式:

输入数据的第一行为X n m,代表矩阵大小为n×m。

从输入数据的第二行开始到文件尾的每一行会出现以下两种操作:

  • L a b c d delta —— 代表将(a,b),(c,d)为顶点的矩形区域内的所有数字加上delta。
  • k a b c d —— 代表求(a,b),(c,d)为顶点的矩形区域内所有数字的和。

请注意,k为小写。

输出格式:

针对每个k操作,在单独的一行输出答案。

输入输出样例

输入样例#1: 复制

X 4 4

L 1 1 3 3 2

L 2 2 4 4 1

k 2 2 3 3

输出样例#1: 复制

12

说明

对于10%的数据,1 ≤ n ≤ 16, 1 ≤ m ≤ 16, 操作不超过200个.

对于60%的数据,1 ≤ n ≤ 512, 1 ≤ m ≤ 512.

对于100%的数据,1 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, -500 ≤ delta ≤ 500,操作不超过200000个,保证运算过程中及最终结果均不超过32位带符号整数类型的表示范围。

by XLk

题解

想写二维线段树。

然而讨论里说卡掉了空间了。

那就硬着头皮写二维树状数组吧。

二维树状数组教做人系列。

对于一维的树状数组,我们知道区间加和区间求和是需要差分并维护两个树状数组的。(不会的可以去用树状数组写一下x谷的线段树模板1)

这个对于二维树状数组同样适用。

那么我们假设\(sum[i][j]\)为差分数组。

\(sum[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1]\)。

为什么要这么假设呢?

因为这样我们可以发现

对于点\((x,y)\)的值就是

\(\sum_{i=1}^x\sum_{j=1}^y\sum_{h=1}^i\sum_{k=1}^j sum[h][k]\)

根据每一次的求值,我们发现以\((x,y)\)为结尾的矩阵,每个差分数组出现的次数为

\(\sum_{i=1}^x\sum_{j=1}^y sum[i][j]*(x-i+1)*(y-j+1)\)

是不是会发现开始变得和一维树状数组求法一样了。

接下来让我们把这个公式拆开食用。

\(\sum_{i=1}^x\sum_{j=1}^y sum[i][j]*(xy+x+y+1)-sum[i][j]*i(y+1)-sum[i][j]*j(x+1)+sum[i][j]*i*j\)

发现只要维护\(sum[i][j],sum[i][j]*i,sum[i][j]*j,sum[i][j]*i*j\)四个树状数组了。

好现在考虑加值。给\((2,2),(3,3)\)的矩阵加上值。

在差分数组里面就是这样的

0 0 0 0 0
0 + 0 - 0
0 0 0 0 0
0 - 0 + 0

就等于正常数组里面的

0 0 0 0 0
0 + + 0 0
0 + + 0 0
0 0 0 0 0

即在给\((x_1,y_1),(x_2,y_2)\)加值时。我们需要给\((x_1,y_1),(x_2+1,y_2+1)\)加,\((x_1,y_2+1),(x_2+1,y_1)\)减。

因为统计数组时,点\((i,j)\)的值为以\((i,j)\)为右下角,\((1,1)\)为左上角的差分矩阵的和。

题解

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int read(){
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} struct node{
int t[2050][2050];
void add(int x,int y,int v){
for(int i=x;i<=n;i+=(i&(-i)))
for(int j=y;j<=m;j+=(j&(-j)))
t[i][j]+=v;
}
int query(int x,int y){
int sum=0;
for(int i=x;i;i-=(i&(-i)))
for(int j=y;j;j-=(j&(-j)))
sum+=t[i][j];
return sum;
}
}Q,Qi,Qj,Qij; void add(int x,int y,int v){
Q.add(x,y,v);Qi.add(x,y,v*x);
Qj.add(x,y,v*y);Qij.add(x,y,v*x*y);
} int query(int x,int y){
return Q.query(x,y)*(x*y+x+y+1)-Qi.query(x,y)*(y+1)-Qj.query(x,y)*(x+1)+Qij.query(x,y);
} int main(){
n=read();m=read();
char opt[10];
while(scanf("%s",opt)==1){
int xa=read(),ya=read(),xb=read(),yb=read();
if(opt[0]=='L'){
int v=read();
add(xa,ya,v);add(xb+1,ya,-v);
add(xb+1,yb+1,v);add(xa,yb+1,-v);
}
else {
printf("%d\n",query(xb,yb)-query(xb,ya-1)-query(xa-1,yb)+query(xa-1,ya-1));
}
}
return 0;
}

[luogu] P4514 上帝造题的七分钟 (树状数组,二维差分)的更多相关文章

  1. BZOJ 3132(上帝造题的七分钟-树状数组求和+2D逆求和数组)

    3132: 上帝造题的七分钟 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 46  Solved: 18[Submit][Status][Discus ...

  2. 【BZOJ3132】上帝造题的七分钟 [树状数组]

    上帝造题的七分钟 Time Limit: 20 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description “第一分钟,X说,要有矩阵 ...

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

    这个思路很巧妙啊 ~ code: #include <cstdio> #include <algorithm> #define N 2050 #define ll int #d ...

  4. bzoj 4822: [Cqoi2017]老C的任务【扫描线+树状数组+二维差分】

    一个树状数组能解决的问题分要用树套树--还写错了我别是个傻子吧? 这种题还是挺多的,大概就是把每个矩形询问差分拆成四个点前缀和相加的形式(x1-1,y1-1,1)(x2.y2,1)(x1-1,y2,- ...

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

    P4514 上帝造题的七分钟 求的是矩阵里所有数的和: 维护四个树状数组: #include<cstdio> #include<cstring> #include<alg ...

  6. P4514 上帝造题的七分钟(二维树状数组)

    P4514 上帝造题的七分钟 二维树状数组 差分维护区间加法,区间求和 #include<cstdio> int read(){ ,f=; ') f=f&&(c!='-') ...

  7. P4514 上帝造题的七分钟

    P4514 上帝造题的七分钟 题意: 二维区间修改 区间查询 --- 错误日志: 写了个 4 重循环忘记调用 \(i\) Solution 二维树状数组 巨尼玛毒瘤 听说二维线段树会 \(MLE\) ...

  8. 洛谷 P4514 上帝造题的七分钟 解题报告

    P4514 上帝造题的七分钟 题目背景 裸体(裸题)就意味着身体(神题). 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n \times m\)矩阵. 第二 ...

  9. 洛谷P4514 上帝造题的七分钟

    P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵. 第二分钟,L说,要能修改,于是便有 ...

随机推荐

  1. 算法22-----托普利茨矩阵leetcode766

    1.题目 如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵. 给定一个 M x N 的矩阵,当且仅当它是托普利茨矩阵时返回 True. 示例 1: 输入: matr ...

  2. Use gdb attach pid and debug it

  3. QT_圆_直线_三角t

    MyImgTest.h: #ifndef MYIMGTEST_H#define MYIMGTEST_H #include <QWidget> class MyImgTest : publi ...

  4. iText、poi操作word2007(读取,生成)

    关于生成word文件以及插入文字.表格.图片等功能,我使用了poi和itext,因为poi插入图片的jar包我在网上查并不是太完全,也可能我没找到如何使用,所以插入图片我用的是itext iText所 ...

  5. ActiveMQ_Windows和Linux版本的安装部署

    1, 保证电脑上安装了jdk6以上版本的java,并配置了好环境变量 : 2, 官方下载地址:http://activemq.apache.org/download-archives.html ,这里 ...

  6. WinServer-AD域控入门

    计算机账户和用户账户的区别 域控中不需要事先建立计算机账户,但必须建立登录用户账户. 计算机只要知道域控管理员或者授权管理账户,就可以利用此账户为所有计算机加域. 计算机加域成功之后,都会在AD管理里 ...

  7. ASP.NET-SOAP、UDDI知识点

    1. 什么是SOAP? 答:是简单访问协议.是在分布式环境中,交换信息并实现远程调用的协议.是一个基于XML的协议.使用SOAP,可以不考虑任何传输协议,但通常还是HTTP协议,可以允许任何类型的对象 ...

  8. ZJOI—— 密码机(2003)

    ZJOI2003密码机,没找到可以测试的网站,就只过了样例~~ 题目描述 一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码.现在请你 ...

  9. l洛谷 P2326 AKN’s PPAP

    P2326 AKN’s PPAP 题目描述 “I have a pen,I have an apple.Eh,Apple-Pen!. I have a pen,I have pineapple.En, ...

  10. 蓝桥杯 - 带分数 (DFS)

      历届试题 带分数   时间限制:1.0s   内存限制:256.0MB        问题描写叙述 100 能够表示为带分数的形式:100 = 3 + 69258 / 714. 还能够表示为:10 ...