牛客第二场-J-farm-二维树状数组
二维树状数组真的还挺神奇的,更新也很神奇,比如我要更新一个区域内的和,我们的更新操作是这样的
add(x1,y1,z);
add(x2+1,y2+1,z);
add(x1,y2+1,-z);
add(x2+1,y1,-z);
我们会想为什么和一维的差这么多,我们不妨这样看
add(x1,y1,z);的更新效果
add(x2+1,y2+1,z);的更新效果
那么这个下半区有两个,我们再更新
add(x1,y2+1,-z);的更新效果
add(x2+1,y1,-z);的更新效果
最后用红的去剪掉黄色部分,就是二维数组的区间更新效果
这样就可以区间更新了,并且这样还可以实现区间求和。
回到这道题
我们可以这样实现,把每种花的种类的坐标存下来
再把每种农药撒的对应区间给存下来,并且更新这数状数组区间,即加一(表示这颗花我又撒了一种农药),
最后我们去遍历这种花,把这种农药的影响减去,看这种花是否为0,如果不是0,就表示这颗肯定会死,并且由于我们每次遍历的是同一种的花,所以不存在重复计算(PS:当时我想这种花,被另外的农药浇了3次以上就会在算其他农药的时候重复计算,实际上是没有的,因为我们每次只遍历这种花,这种花遍历后,就不会出现了)
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define inf 0x3f3f3f3f
const int MAXN=1e6+;
using namespace std;
int n,m,q;
struct node{
int x1,y1,x2,y2;
};
vector<pair<int,int> >point[MAXN];//存花种类所在的位置
vector<node>p[MAXN];//存询问点
vector<int>tree[MAXN];//
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int z){//二位树状数组的维护
//cout<<n<<"--"<<m<<endl;
for (int i=x;i<=n;i+=lowbit(i)){ for (int j=y;j<=m;j+=lowbit(j)){
tree[i][j]+=z;
}
}
}
void updata(int x1,int y1,int x2,int y2,int z){//二维树状数组的更新操作
add(x1,y1,z);
add(x2+,y2+,z);
add(x1,y2+,-z);
add(x2+,y1,-z);
}
int query(int x,int y){
int ans=;
for (int i=x;i;i-=lowbit(i)){
for(int j=y;j;j-=lowbit(j)){
ans+=tree[i][j];
}
}
return ans;
}
int main(){ scanf("%d %d %d",&n,&m,&q);
for (int i=;i<=n;i++)tree[i].resize(m+);//
for (int i=;i<=n;i++){
for (int j=;j<=m;j++){
int z;
scanf("%d",&z);
point[z].push_back(make_pair(i,j));//把每个种花对于的坐标存起来
}
}
for (int i=;i<=q;i++){
int x1,x2,y1,y2,k;
scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&k);
updata(x1,y1,x2,y2,);//更新二维树状数组树
p[k].push_back(node{x1,y1,x2,y2});//把这个农药类型的K更改保持起来
}
int ans=;
for (int i=;i<=n*m;i++){
if (point[i].size()>){
for (int j=;j<p[i].size();j++)
updata(p[i][j].x1,p[i][j].y1,p[i][j].x2,p[i][j].y2,-);//把这种农药的所有更改都删除
for (int j=;j<point[i].size();j++){
if (query(point[i][j].first,point[i][j].second))//检查是否含为0,即是否有不是这种类型的更改
ans++;
}
for (int j=;j<p[i].size();j++)
updata(p[i][j].x1,p[i][j].y1,p[i][j].x2,p[i][j].y2,);//把这种更改删除
}
}
printf("%d\n",ans);
return ;
}
牛客第二场-J-farm-二维树状数组的更多相关文章
- 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)
题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...
- 牛客第二场 J farm
White Rabbit has a rectangular farmland of n*m. In each of the grid there is a kind of plant. The pl ...
- MooFest_二维树状数组
Description Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a s ...
- 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?
开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...
- 牛客训练六:海啸(二维树状数组+vector函数的使用)
题目链接:传送门 思路: 二维树状数组, vector(first,last)函数中assign函数相当于将first中的函数清空,然后将last中的值赋值给first. 参考文章:传送门 #incl ...
- 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)
BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...
- BZOJ3132 上帝造题的七分钟 【二维树状数组】
题目 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的 ...
- 二维树状数组——SuperBrother打鼹鼠(Vijos1512)
树状数组(BIT)是一个查询和修改复杂度都为log(n)的数据结构,主要用于查询任意两位之间的所有元素之和,其编程简单,很容易被实现.而且可以很容易地扩展到二维.让我们来看一道很裸的二维树状数组题: ...
- tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树
P1716 - 上帝造题的七分钟 From Riatre Normal (OI)总时限:50s 内存限制:128MB 代码长度限制:64KB 背景 Background 裸体就意味着 ...
- [Scoi2014]方伯伯的玉米田 二维树状数组+动态规划
考试最后半个小时才做这道题.十分钟写了个暴力还写挂了..最后默默输出n.菜鸡一只. 这道题比较好看出来是动规.首先我们要明确一点.因为能拔高长度任意的一段区域,所以如果从i开始拔高,那么一直拔高到n比 ...
随机推荐
- HighCharts初测试
把HighChart嵌入到博客中.
- django生命周期和事件委派
这是事件委派如果不用事件委派 直接绑定的话,新添加的按钮不会有删除或者编辑的功能 上面是事件委派的代码 新添加的编辑按钮可以弹出123 django生命周期: 这是Django的生命周期 首先会通 ...
- centos7下安装docker(12.2自定义网络)
通常默认的情况下我们使用的是docker的bridge的网络,用户也可以根据自己的业务需要,创建user-defined docker 提供三种user-defined网络驱动:bridge,over ...
- 深入浅出RxJava(三:响应式的好处)
在第一篇中,我介绍了RxJava的基础知识.第二篇中,我向你展示了操作符的强大.但是你可能仍然没被说服.这篇里面,我讲向你展示RxJava的其他的一些好处,相信这篇足够让你去使用Rxjava. 错误处 ...
- 关于一台机器部署多个tomcat的小记
一台机器部署多个tomcat在很多时候都是有可能的,比如说多个tomcat配合nginx负载更可能好的利用CPU,或者更新程序时做主备切换等. 1.直接下载或者复制一个已有的tomcat,第一个tom ...
- php结合redis高并发下,悲观锁解决数据二次写入
悲观锁 在悲观锁的情况下,为了保证事务的隔离性,就须要一致性锁定读.读取数据时给加锁,其他事务无法改动这些数据.改动删除数据时也要加锁,其他事务无法读取这些数据. 在做数据缓存的时候,通常都是把数据从 ...
- go标准库的学习-reflect
参考: https://studygolang.com/pkgdoc http://c.biancheng.net/golang/concurrent/ 导入方式: import "refl ...
- Linux kernel 之 socket 创建过程分析
重要结构体 struct socket 结构体 // 普通的 BSD 标准 socket 结构体 // socket_state: socket 状态, 连接?不连接? // type: socket ...
- ubuntu开机自动运行用Qt写的程序
这里介绍一种在ubuntu系统开机自动运行使用Qt编写的程序的方法.首先要注意要自动运行Qt编的程序,不需要先打开Qt,而是直接运行编译好的与工程名同名的可执行文件即可,比如我要运行的工程为QRDec ...
- 高阶函数 - aop面向切面编程
Function.prototype.before = function(beforefn) { var __self = this; return function() { beforefn.app ...