牛客第二场-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比 ...
随机推荐
- Windows 10更新后频繁死机、假死(SSD)
问题详情: 新版的Windows改变了更新策略,无法设置为不更新系统.在系统更新后,之前的部分设定也会神奇丢失,包括之前设定的解决的这个卡顿问题.于是重新爬文章找解决方案,在这里做个备份. 本文章内容 ...
- kettle 合并记录步骤中的 关键字段和 比较字段的说明
该步骤用于将两个不同来源的数据合并,这两个来源的数据分别为旧数据和新数据,该步骤将旧数据和新数据按照指定的关键字匹配.比较.合并. 需要设置的参数: 旧数据来源:旧数据来源的步骤 新数据来源.新数据来 ...
- C++基础算法学习——汉洛塔问题
汉诺塔问题古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图).有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中, ...
- FileInputStream与FileOutputStream学习笔记
这是我的第一篇博客,纪念一下吧! 最近学习了IO流,想着学长说的话,就突然想要写写博客了,别管这是什么逻辑了,进入正题. 一.FileInputStream 1.概念 FileInputStream是 ...
- Pandas 库中excel的读写方法介绍
首选:https://blog.csdn.net/u014597198/article/details/83104653 其次:https://blog.csdn.net/qq_34377830/ar ...
- 阿里八八β阶段Scrum(4/5)
今日进度 黄梅玲: 图表绘制与实时更新的完成 刘晓: 数据分析表格部分生成完成 张岳: 初步完成简易的桌面控件 陈裕鹏: 事件添加TAG标签的功能完成,此外信息抽取算法也基本完成并PULL,但与项目产 ...
- Python3编写网络爬虫11-数据存储方式四-关系型数据库存储
关系型数据库存储 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表保存的,所以它的存储方式就是行列组成的表.每一列是一个字段,每一行是一条记录.表可以看作某个实体的集合,而实体之间存在联系, ...
- jeDate 日期控件
写在前面的话: 最近在做一个日期范围的功能,研究了一个12306网站的日期范围选择,他用的是jcalendar.js,没有直接在日历插件里面做判断开始时间小于结束时间 而是自己在代码里面做了判断如下: ...
- 转载 信号量 <第六篇>
一.ManualResetEvent 该对象有两种信号量状态True和False.构造函数设置初始状态.简单来说, 如果构造函数由true创建,则第一次WaitOne()不会阻止线程的执行,而是等待R ...
- sh脚本文件的运行
sh脚本文件的运行mac终端下运行shell脚本 1.写好自己的 脚本,比如test-bash.sh 2.打开终端 执行,方法一: 输入命令 ./test-bash.sh , 方法二:直接把 aa.s ...