牛客第二场-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比 ...
随机推荐
- SELinux 是什么?
一.SELinux的历史 SELinux全称是Security Enhanced Linux,由美国国家安全部(National Security Agency)领导开发的GPL项目,它拥有一个灵活而 ...
- 【PAT】B1071 小赌怡情(15 分)
水题一道,直接贴代码 #include<cstdio> #include<string.h> int main(){ //玩家的筹码数.以及 int T,K;scanf(&qu ...
- JavaScript中数组的增删改查以及应用方式
数组的增加方法 1.push()方法向数组中末尾添加一个元素,原数组改变 var arr=[1,2,3,4]; var arr1=arr.push(6); console.log(arr);//打印出 ...
- 回文数的golang实现
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数 输入: 输出: true 输入: - 输出: false 解释: 从左向右读, 为 - . 从右向左读, 为 - ...
- 计算机基础-CPU
CPU(Central Processing Unit中央处理器)由运算器和控制器组成--微机性能的集成度最高的核心部件 1.金属触点 2.附带散热器 风冷式 热管散热式 水冷式等 扣具结构要和CPU ...
- CRM项目之stark组件(2)
那么从今天开始呢,我们就要开始设计属于我们自己的admin组件,起个名字就叫stark吧(当然你愿意叫什么都可以). stark组件之四步走 仿照admin组件实现流程,stark组件要实现四件事情: ...
- 通过css3,实现加载转动贝塞尔曲线动画
参考博客:http://blog.jobbole.com/94966/ css代码: .loading { position : relative; display : inline-block; w ...
- 基于Redis的INCR实现一个限流器
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...
- P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- QT获取窗口大小和位置等信息
QT窗口尺寸,窗口大小和大小改变引起的事件 QResizeEvent. 来源:http://blog.csdn.net/dbzhang800/article/details/6741344?reloa ...