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. oracle中单引号的处理

    当想让输出的结果中字段带有单引号', 场景一:连续三个单引号''' select '''helin''' from dual; ---'helin' 场景二:拼接字段的结果集--连续4个单引号 sel ...

  2. 全球NTP服务器列表

    全球- pool.ntp.org 欧洲- europe.pool.ntp.org 亚洲- asia.pool.ntp.org 大洋洲- oceania.pool.ntp.org 北美- north-a ...

  3. Github添加SSHkey

    Git详细教程可参考廖雪峰的Git教程 1. 打开 Git Bash,输入cd ~/.ssh——回车(看你是否有了ssh key 密钥,有了就备份): 2. 输入ssh-keygen -t rsa - ...

  4. python3 将两个列表生成一个字典

    需求: 存在两个list如下 list1 = ["one", "two", "three"] list2 = ["1", ...

  5. 单元测试Struts2的Action(包含源码)

    很久没有从头搭建Struts2的环境了.最近,认真实践了单元测试Struts2.Spring等Java项目. 今天特意写的是单元测试Struts2的Action,遇到了不少问题,果然是实践出真知啊. ...

  6. leetcode笔记:Find Median from Data Stream

    一. 题目描写叙述 Median is the middle value in an ordered integer list. If the size of the list is even, th ...

  7. H2数据库入门使用

    H2数据库入门使用 学习了: https://www.cnblogs.com/xdp-gacl/p/4171024.html http://www.cnblogs.com/xdp-gacl/p/417 ...

  8. [TypeScript] Generic Functions, class, Type Inference and Generics

    Generic Fucntion: For example we have a set of data and an function: interface HasName { name: strin ...

  9. 多本Web前端深度修炼书籍(提供网盘下载链接)

    书籍介绍:这本书涵盖了html5新增标签和功能,而且提供了jquerymobile,Phonegap,Sencha Touch框架的介绍和应用,最后还带了一个移动web应用的样例,绝对是移动web开发 ...

  10. C++ STL之list具体解释

    list容器是一个双向链表,能够高效地进行插入删除元素. 构造函数 list<Elem> c;//空list list<int> c(3);//创建一个含有三个默认值是0的元素 ...