[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说,要能修改,于是便有 ...
随机推荐
- P3376 【模板】网络最大流(luogu)
P3376 [模板]网络最大流(luogu) 最大流的dinic算法模板(采取了多种优化) 优化 时间 inline+当前弧+炸点+多路增广 174ms no 当前弧 175ms no 炸点 249 ...
- linux yum安装找不到源
1先说问题: 服务器装麒麟系统后安装gis地图(其实就是部署一套地图服务),因为是内网,所以所有需要的包都放在一个iso文件中了,需要用mount命令去加载之,然后配置*.repo文件(源文件配置), ...
- event 下鼠标坐标的获取
event.clientX.event.clientY 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条.IE事件和标准事件都定义了这2个属性 event.pageX ...
- [poj 2976] Dropping tests (分数规划 二分)
原题: 传送门 题意: 给出n个a和b,让选出n-k个使得(sigma a[i])/(sigma b[i])最大 直接用分数规划.. code: //By Menteur_Hxy #include & ...
- centos7最小化安装Oracle11gR2
1.准备CentOS 7 系统环境 我以 CentOS-7-x86_64-DVD-1511.iso 为例,简述Oracle 11g的安装过程. 由于是使用静默模式(silent)安装的,无需使用图形化 ...
- Linux mysql-5.7.17安装 教程
1.下载安装文件 #mkdir /data #mkdir /data/software #cd /data/software #wget http://dev.mysql.com/get/Downl ...
- ansible 定义主机用户和密码
定义主机组用户和密码 [webservers] ansible[01:04] ansible_ssh_user='root' ansible_ssh_pass='AAbb0101' [root@ftp ...
- Vue入门教程(2)
小白入门学习vue和vue实例,vue总结 这就是我脑海中的 Vue 知识体系: 一句话概况了 Vue 通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件 Vue 的创建 我们的学习目的肯定 ...
- Action访问ServletAPI的三种方式
一.前言 Struts是一种基于MVC设计模式的web应用框架,主要担任C的角色,用于分离页面显示和业务逻辑处理,那其实在我们学习jsp的时候学过一个具有类似功能的东西——servlet.其实Stru ...
- HDU 4089
很容易列出方程 设dp[i][j]为排在第i位置,总共有j个人排队到达目标状态的概率 i=1 dp[i][j]=p4+p1*dp[i][j]+p2*dp[j][j] 2<=i<=k dp[ ...