P4514 上帝造题的七分钟

题目描述

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

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

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

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

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

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

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

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

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

二维树状数组裸题。

定义二维差分数组:

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

如何维护\(1,1\)到\(i,j\)的二维前缀和?

\[sum(x)(y)=\sum_{i=1}^x\sum_{j=1}^y\sum_{k=1}^i\sum_{l=1}^jd(i)(j)\\
=\sum_{i=1}^x\sum_{j=1}^yd(i)(j)*(x+1-i)*(y+1-i)\\
=(x+1)*(y+1)*\sum_{i=1}^x\sum_{j=1}^yd(i)(j)-(y+1)\sum_{i=1}^x\sum_{j=1}^yd(i)(j)*i\\-(x+1)*\sum_{i=1}^x\sum_{j=1}^y*j+\sum_{i=1}^x\sum_{j=1}^y*d(i)(j)*i*j
\]

按照上述式子维护四个前缀和数组即可。

具体操作:

code:

void add(int posx,int posy,int k){
for(int i=posx;i<=n;i+=(i&-i)){
for(int j=posy;j<=m;j+=(j&-j)){
sum1[i][j]+=k;
sum2[i][j]+=k*posx;
sum3[i][j]+=k*posy;
sum4[i][j]+=k*posx*posy;
}
}
}
int query(int posx,int posy){
int re=0;
for(int i=posx;i>=1;i-=(i&-i)){
for(int j=posy;j>=1;j-=(j&-j)){
re+=((posx+1)*(posy+1))*sum1[i][j]-(posy+1)*sum2[i][j]-(posx+1)*sum3[i][j]+sum4[i][j];
}
}
return re;
}
void add_wx(int x1,int x2,int y1,int y2,int k){
add(x1,y1,k);
add(x1,y2+1,-k);
add(x2+1,y1,-k);
add(x2+1,y2+1,k);
}
int query_wx(int x1,int x2,int y1,int y2){
return query(x2,y2)-query(x1-1,y2)-query(x2,y1-1)+query(x1-1,y1-1);
}

针对本题:

code:

// luogu-judger-enable-o2
#include <iostream>
#include <cstdio> using namespace std; const int wx=3017; inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
} int sum1[wx][wx];
int sum2[wx][wx];
int sum3[wx][wx];
int sum4[wx][wx];
int n,m;
char opt[4]; /* d[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1]
sum1[i][j]-->d[i][j]
sum2[i][j]-->d[i][j]*i
sum3[i][j]-->d[i][j]*j
sum4[i][j]-->d[i][j]*i*j sum[x1][y1][x2][y2]=(x+1)*(y+1)*sum1[i][j]-(y+1)*sum2[i][j]-(x+1)*sum3[i][j]+sum4[i][j]。 */ void add(int posx,int posy,int k){
for(int i=posx;i<=n;i+=(i&-i)){
for(int j=posy;j<=m;j+=(j&-j)){
sum1[i][j]+=k;
sum2[i][j]+=k*posx;
sum3[i][j]+=k*posy;
sum4[i][j]+=k*posx*posy;
}
}
} int query(int posx,int posy){
int re=0;
for(int i=posx;i>=1;i-=(i&-i)){
for(int j=posy;j>=1;j-=(j&-j)){
re+=((posx+1)*(posy+1))*sum1[i][j]-(posy+1)*sum2[i][j]-(posx+1)*sum3[i][j]+sum4[i][j];
}
}
return re;
} void add_wx(int x1,int x2,int y1,int y2,int k){
add(x1,y1,k);
add(x1,y2+1,-k);
add(x2+1,y1,-k);
add(x2+1,y2+1,k);
} int query_wx(int x1,int x2,int y1,int y2){
return query(x2,y2)-query(x1-1,y2)-query(x2,y1-1)+query(x1-1,y1-1);
} int main(){
scanf("%s");
n=read(); m=read();
while(scanf("%s",opt+1)!=EOF){
if(opt[1]=='L'){
int x,y,z,c,k;
x=read(); y=read(); z=read(); c=read(); k=read();
add_wx(x,z,y,c,k);
}
else{
int x,y,z,c;
x=read(); y=read(); z=read(); c=read();
printf("%d\n",query_wx(x,z,y,c));
}
}
return 0;
}

二维树状数组总结&&【洛谷P4514】 上帝造题的七分钟的更多相关文章

  1. 模板:二维树状数组 【洛谷P4054】 [JSOI2009]计数问题

    P4054 [JSOI2009]计数问题 题目描述 一个n*m的方格,初始时每个格子有一个整数权值.接下来每次有2种操作: 改变一个格子的权值: 求一个子矩阵中某种特定权值出现的个数. 输入输出格式 ...

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

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

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

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

  4. 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]

    题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...

  5. 洛谷P4145——上帝造题的七分钟2 / 花神游历各国

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  6. 洛谷P4145上帝造题的七分钟——区间修改

    题目:https://www.luogu.org/problemnew/show/P4145 区间开平方,可以发现其实开几次就变成1,不需要开了,所以标记一下,每次只去开需要开的地方: 原来写的并查集 ...

  7. 洛谷 P4145 上帝造题的七分钟2 / 花神游历各国

    洛谷 这题就是区间开根号,区间求和.我们可以分块做. 我们记布尔数组vis[i]表示第i块中元素是否全部为1. 因为显然当一个块中元素全部为1时,并不需要对它进行根号操作. 我们每个块暴力开根号,因为 ...

  8. 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  9. 洛谷P4054 [JSOI2009]计数问题(二维树状数组)

    题意 题目链接 Sol 很傻x的题.. c才100, n, m才300,直接开100个二维树状数组就做完了.. #include<bits/stdc++.h> using namespac ...

  10. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

    题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...

随机推荐

  1. 用nfs挂载内核时出错 ERROR: Cannot umount的解决办法

    SMDK2440 # nfs 30000000 192.168.1.106:/work/nfs_root/uImage                         ERROR: resetting ...

  2. Socket编程, 在server端read()函数调用后显示错误:Transport endpoint is not connected (犯了低级错误)

    for(;;){ socklen_t len = sizeof(client_address); connfd = accept(listenfd, (struct sockaddr *)&c ...

  3. 第三章 深入分析Java Web的中文乱码问题(待续)

    几种常见的编码格式 在Java中需要编码的场景 在Java中如何编解码 在Java Web中涉及的编解码 在JS中的编码问题 常见问题分析 一种繁简转换的实现方式

  4. WCF上传大文件处理方法

    <system.serviceModel> <bindings> <basicHttpBind> <Binding name=" maxReceiv ...

  5. cmake的一个编译报错

    在一台新搭建的服务器上执行cmake的时候,报了如下错误: $ cmake ./ -- The C compiler identification is unknown -- The CXX comp ...

  6. LINUX 使用DBCA创建ORACLE数据库

  7. 【android】关于自己实现adapter后gridview中item无法被选中的解决方法

    有时候,自己继承实现了baseadapter将其赋给gridview之后,gridview会十分奇怪的无法选中内部的item. 经过仔细研究,我发现是在继承的时候多复写了几个方法,解决方法就是,只保留 ...

  8. auth 权限控制

    一. 权限介绍所谓权限控制,大部分是在管理后台上使用.比如超级管理员登录,会得到所有操作的控制权:认证专员,只能给会员做认证操作:审核专员,只能操作内容的审核.删除.加精等操作,以此类推.那么 Thi ...

  9. SpringBoot05 数据操作02 -> JPA接口详解

    概览 JpaRepository 继承 PagingAndSortingRepository 继承 CrudRepository 继承 Repository 1 Repository 这是一个空接口, ...

  10. QGraphicsScene绘制网格背景

    博客转载自:https://blog.csdn.net/u010177010/article/details/51496038 //两条轴线QPolygonF myPolygon1; myPolygo ...