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)\)的矩阵加上值。

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

  1. 0 0 0 0 0
  2. 0 + 0 - 0
  3. 0 0 0 0 0
  4. 0 - 0 + 0

就等于正常数组里面的

  1. 0 0 0 0 0
  2. 0 + + 0 0
  3. 0 + + 0 0
  4. 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)\)为左上角的差分矩阵的和。

题解

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cstring>
  6. using namespace std;
  7. int n,m;
  8. int read(){
  9. int x=0,w=1;char ch=getchar();
  10. while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
  11. while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
  12. return x*w;
  13. }
  14. struct node{
  15. int t[2050][2050];
  16. void add(int x,int y,int v){
  17. for(int i=x;i<=n;i+=(i&(-i)))
  18. for(int j=y;j<=m;j+=(j&(-j)))
  19. t[i][j]+=v;
  20. }
  21. int query(int x,int y){
  22. int sum=0;
  23. for(int i=x;i;i-=(i&(-i)))
  24. for(int j=y;j;j-=(j&(-j)))
  25. sum+=t[i][j];
  26. return sum;
  27. }
  28. }Q,Qi,Qj,Qij;
  29. void add(int x,int y,int v){
  30. Q.add(x,y,v);Qi.add(x,y,v*x);
  31. Qj.add(x,y,v*y);Qij.add(x,y,v*x*y);
  32. }
  33. int query(int x,int y){
  34. 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);
  35. }
  36. int main(){
  37. n=read();m=read();
  38. char opt[10];
  39. while(scanf("%s",opt)==1){
  40. int xa=read(),ya=read(),xb=read(),yb=read();
  41. if(opt[0]=='L'){
  42. int v=read();
  43. add(xa,ya,v);add(xb+1,ya,-v);
  44. add(xb+1,yb+1,v);add(xa,yb+1,-v);
  45. }
  46. else {
  47. printf("%d\n",query(xb,yb)-query(xb,ya-1)-query(xa-1,yb)+query(xa-1,ya-1));
  48. }
  49. }
  50. return 0;
  51. }

[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. js 获取对象长度

    获取对象的程度,可以这样获取: var myObj = {a:1,b:2,c:3} var arr = Object.keys(myObj);var len = arr.length  console ...

  2. BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)

    明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...

  3. BZOJ 1415 [NOI2005]聪聪与可可 (概率DP+dfs)

    题目大意:给你一个无向联通图,节点数n<=1000.聪聪有一个机器人从C点出发向在M点的可可移动,去追赶并吃掉可可,在单位时间内,机器人会先朝离可可最近的节点移动1步,如果移动一步机器人并不能吃 ...

  4. nmcli

    [root@web01 ~]# nmcli device status DEVICE TYPE STATE CONNECTION eth0 ethernet connected eth0 lo loo ...

  5. 新手学python-Day2-变量和循环判断

    第二天作业: 初探三级菜单,凭现有知识,注意变量可以不声明,但要提前赋值! 此处shuru = '' 可以不写,因为第7行被赋值了,如果只调用shuru不赋值就会报错 shuru = '' sheng ...

  6. 洛谷P5238 整数校验器

    看到没有边读入边处理的,我来水一发 我们要看一下有那些情况是格式不合法的 单独的负号 -0(后面可以有其他数字) 0 +(后面一些数字) 我们用快速读入的方法 读取字符进行处理 还有可能超出范围的 考 ...

  7. mybatis中sql标签和include标签

    1.首先定义一个sql标签,一定要定义唯一id.(name,age是要查询的字段) <sql id="Base_Column_List" >name,age</s ...

  8. Spring IOC过程

    https://www.processon.com/diagraming/5c96171fe4b0f88919b98497 1. AbstractApplicationContext:执行refres ...

  9. 使用默认system_health分析死锁(Deadlock)

    在2008之前我们分析死锁须要用profiler trace或者trace flag 1222,1204.在2008中引入了一个新功能:Extended Events(扩展事件).能够监控Deadlo ...

  10. Hibernate中的HQL

    一.查询所有的时候 List<Company> list=session.createQuery("from Company as c order by c.cid desc&q ...