[luogu] P4514 上帝造题的七分钟 (树状数组,二维差分)
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 上帝造题的七分钟 (树状数组,二维差分)的更多相关文章
- BZOJ 3132(上帝造题的七分钟-树状数组求和+2D逆求和数组)
3132: 上帝造题的七分钟 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 46 Solved: 18[Submit][Status][Discus ...
- 【BZOJ3132】上帝造题的七分钟 [树状数组]
上帝造题的七分钟 Time Limit: 20 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description “第一分钟,X说,要有矩阵 ...
- BZOJ 3132: 上帝造题的七分钟 树状数组+差分
这个思路很巧妙啊 ~ code: #include <cstdio> #include <algorithm> #define N 2050 #define ll int #d ...
- bzoj 4822: [Cqoi2017]老C的任务【扫描线+树状数组+二维差分】
一个树状数组能解决的问题分要用树套树--还写错了我别是个傻子吧? 这种题还是挺多的,大概就是把每个矩形询问差分拆成四个点前缀和相加的形式(x1-1,y1-1,1)(x2.y2,1)(x1-1,y2,- ...
- P4514 上帝造题的七分钟——二维树状数组
P4514 上帝造题的七分钟 求的是矩阵里所有数的和: 维护四个树状数组: #include<cstdio> #include<cstring> #include<alg ...
- P4514 上帝造题的七分钟(二维树状数组)
P4514 上帝造题的七分钟 二维树状数组 差分维护区间加法,区间求和 #include<cstdio> int read(){ ,f=; ') f=f&&(c!='-') ...
- P4514 上帝造题的七分钟
P4514 上帝造题的七分钟 题意: 二维区间修改 区间查询 --- 错误日志: 写了个 4 重循环忘记调用 \(i\) Solution 二维树状数组 巨尼玛毒瘤 听说二维线段树会 \(MLE\) ...
- 洛谷 P4514 上帝造题的七分钟 解题报告
P4514 上帝造题的七分钟 题目背景 裸体(裸题)就意味着身体(神题). 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n \times m\)矩阵. 第二 ...
- 洛谷P4514 上帝造题的七分钟
P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了000的n×mn×mn×m矩阵. 第二分钟,L说,要能修改,于是便有 ...
随机推荐
- js 获取对象长度
获取对象的程度,可以这样获取: var myObj = {a:1,b:2,c:3} var arr = Object.keys(myObj);var len = arr.length console ...
- BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)
明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...
- BZOJ 1415 [NOI2005]聪聪与可可 (概率DP+dfs)
题目大意:给你一个无向联通图,节点数n<=1000.聪聪有一个机器人从C点出发向在M点的可可移动,去追赶并吃掉可可,在单位时间内,机器人会先朝离可可最近的节点移动1步,如果移动一步机器人并不能吃 ...
- nmcli
[root@web01 ~]# nmcli device status DEVICE TYPE STATE CONNECTION eth0 ethernet connected eth0 lo loo ...
- 新手学python-Day2-变量和循环判断
第二天作业: 初探三级菜单,凭现有知识,注意变量可以不声明,但要提前赋值! 此处shuru = '' 可以不写,因为第7行被赋值了,如果只调用shuru不赋值就会报错 shuru = '' sheng ...
- 洛谷P5238 整数校验器
看到没有边读入边处理的,我来水一发 我们要看一下有那些情况是格式不合法的 单独的负号 -0(后面可以有其他数字) 0 +(后面一些数字) 我们用快速读入的方法 读取字符进行处理 还有可能超出范围的 考 ...
- mybatis中sql标签和include标签
1.首先定义一个sql标签,一定要定义唯一id.(name,age是要查询的字段) <sql id="Base_Column_List" >name,age</s ...
- Spring IOC过程
https://www.processon.com/diagraming/5c96171fe4b0f88919b98497 1. AbstractApplicationContext:执行refres ...
- 使用默认system_health分析死锁(Deadlock)
在2008之前我们分析死锁须要用profiler trace或者trace flag 1222,1204.在2008中引入了一个新功能:Extended Events(扩展事件).能够监控Deadlo ...
- Hibernate中的HQL
一.查询所有的时候 List<Company> list=session.createQuery("from Company as c order by c.cid desc&q ...