小a的轰炸游戏

题目链接:https://ac.nowcoder.com/acm/contest/317/E

思路

这题考查的是对差分数组原理和前缀和的理解。

四个数组分别记录朝着四个方向下放的个数最后求个前缀,就代表着这一行中从这个点开始作为起点的轰炸区域个数,四个数组分别向着四个方向下放最终得到的四个数组分别是前。

4个数组对应下面4条箭头:

图中的绿色是要进行区间操作的菱形。红色圆圈是打的+1操作,蓝色圆圈是打的-1操作。它们是成对出现的,每个红色圆圈都有一个蓝色圆圈来消除它。 它们的标记传递方向是那个紫色的箭头。所以有四种传递方向。就要有四个标记数组。这样传递的话就可以按行遍历,边遍历边下传。

在矩形中,我们在四个角上进行++--,然后利用差分的性质,就解决了区间更新,因为矩形的差分是横着或者竖着的,最后的求和非常容易,但是这里不一样。最后看了题解豁然大悟,原来差分还可以动态的来,本行的差分数组使用完了,还可以把差分数组下传,继续在下一层继续起到作用。

由于可能出现越界的情况,但是标记还是需要处理的。所以就要加个偏移量来进行处理,但是最后计算,只是算原来的矩形。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 3030,ADD = 1000; //ADD表示偏移量 防止越界
int a[MAX][MAX],b[MAX][MAX],c[MAX][MAX],d[MAX][MAX]; //abcd4个数组分别表示4个方向 //上半部分
void up(int x,int y,int l) {
a[x-l/2][y]++,b[x-l/2][y+1]--;
a[x+1][y-l/2-1]--,b[x+1][y+l/2+2]++;
} //下半部分
void down(int x,int y,int l){
c[x+1][y-l/2+1]++,d[x+1][y+l/2]--;
c[x+l/2+1][y+1]--,d[x+l/2+1][y]++;
} int main() {
int n,m,q;
cin>>n>>m>>q;
for(int op,x,y,l,i = 1; i<=q; i++) {
scanf("%d%d%d%d",&op,&x,&y,&l);
x+=ADD,y+=ADD; //加上偏移量 防止越界
if(op == 1) up(x,y,l),down(x,y,l);
if(op == 2) up(x,y,l);
}
//差分数组 差分传递
for(int i = 1; i<=n+ADD*2; i++) {
for(int j = 1; j<=m+ADD*2; j++) {
a[i][j] += a[i-1][j+1];
b[i][j] += b[i-1][j-1];
c[i][j] += c[i-1][j-1];
d[i][j] += d[i-1][j+1];
}
} //计算异或和
int ans = 0;
for(int i = 1; i<=n+ADD*2; i++) {
int tmp = 0;
for(int j = 1; j<=m+ADD*2; j++) {
tmp += a[i][j] + b[i][j] + c[i][j] + d[i][j];
if(i>=ADD+1 && i<=ADD+n && j>=ADD+1 && j<=ADD+m) ans ^=tmp;
}
}
cout << ans <<endl;
return 0 ;
}

差分数组|小a的轰炸游戏-牛客317E的更多相关文章

  1. 算法题14 小Q歌单,牛客网,腾讯笔试题

    算法题14 小Q歌单,牛客网,腾讯笔试题 题目: 小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌 ...

  2. [动态差分+二维前缀和][小a的轰炸游戏]

    链接:https://ac.nowcoder.com/acm/contest/317/E来源:牛客网 题目描述 小a正在玩一款即时战略游戏,现在他要用航空母舰对敌方阵地进行轰炸 地方阵地可以看做是n× ...

  3. 小a的轰炸游戏(差分,前缀和)

    题目传送门 题意: 给出一个n*m的矩形,然后有两个操作. 1操作,对一个给出的菱形,对菱形范围内的东西进行+1. 2操作,对一个上半菱形的区域,进行+1操作. 最后求矩形内各个数的异或和. 思路: ...

  4. 小sun的假期【牛客】

    链接:https://ac.nowcoder.com/acm/contest/1085/A来源:牛客网 应肖老师要求前来更新水一水 题目描述 小 sun 非常喜欢放假,尤其是那种连在一起的长假,在放假 ...

  5. 小A的柱状图_via牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28537/Q 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语 ...

  6. 小C的记事本_via牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28537/G 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K,其他语 ...

  7. 小a的轰炸游戏 (差分)

    我是看题解的! 这道题还是有很多细节,当然,是一道差分的好题! 题意:有2种飞机,一种是只炸上半菱形,一种是炸整个菱形.问所有区域内的所有格子的异或和. 思路:用前缀和思路: 这样遍历过去就完成了一次 ...

  8. 小a与"204"(牛客)

    原题 公式 中间数字与变量之间乘号bug省略可能看着有点别扭例如8x2为8*x2 首先设扫一遍后0的个数为x0 2的个数为x2 4的个数为x4 ①如果x0=x4 ans=32*x4+4 ②如果x0&g ...

  9. 小a的排列(牛客)

    题目 题意: 一个长度为n的排列.输入n个数 a[ i ],a[ i ] ∈ [1,n],要求找到长度最小的区间 [ l , r ],满足区间[ l , r ]内的数是连续的,且同时包含 数 x 和 ...

随机推荐

  1. sqlserver Distributed Transaction 分布式事务

    在webapi+ef+sqlserver开发项目时,利用transcope实现应用层级的事务时,偶尔会报分布式事务错误,而且很而复现,特别蛋疼.现将自己的解决方法初步整理下. 分析原因:搭建repos ...

  2. HDU 6300

    Problem Description Chiaki has 3n points p1,p2,…,p3n. It is guaranteed that no three points are coll ...

  3. django之admin源码解析

    解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...

  4. MyBatis学习(一)简单入门程序

    MyBatis入门学习 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名 ...

  5. Linux基础命令---文本过滤colrm

    colrm 从标准输入读取数据,删除指定的列,然后送到标准输出.如果用一个参数调用,则将从指定的列开始删除每一行的列.如果使用两个参数调用,则将删除从第一列到最后一列的列.列编号以第1列开始. 此命令 ...

  6. Linux基础命令---文本编辑ex

    ex ex会启动vim编辑器,它的执行效果和vim –E相同.从ex模式回到普通模式,可以在vim中输入:vim. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.op ...

  7. linux下php中文UTF-8转换Unicode方法和注意事项

    先说下遇到问题:1.php没有内置unicode_ecode函数可以直接使用 2.网上很多资料都是用$str = iconv($encoding, 'UCS-2', $str); window下转换出 ...

  8. TensorFlow for distributed

    TensorFlow for distributed 本目录包括了运行时分布式TensorFlow的实现,其底层使用了gRPC 作为进程内通信的支持库. Quick start 首先,需要构建一个Te ...

  9. redis安装--转

    第一部分:安装redis 希望将redis安装到此目录 1 /usr/local/redis 希望将安装包下载到此目录 1 /usr/local/src 那么安装过程指令如下: 1 2 3 4 5 6 ...

  10. C++ 开源库列表

    https://zh.cppreference.com/w/cpp/links/libs