[luogu3801]红色的幻想乡
题目描述
经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放。
我们将幻想乡看做是一个n*m的方格地区,一开始没有任何一个地区被红雾遮盖。蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区。如果两阵红雾碰撞,则会因为密度过大而沉降消失。
灵梦察觉到了这次异变,决定去解决它。但在解决之前,灵梦想要了解一片范围红雾的密度。可以简述为两种操作:
1 x y 蕾米莉亚站在坐标(x,y)的位置向四个方向释放无限长的红雾。
2 x1 y1 x2 y2 询问左上点为(x1,y1),右下点为(x2,y2)的矩形范围内,被红雾遮盖的地区的数量。
解法
因为对于一次修改,一定会修改到底,怎么说的,就是这一列或者是这一整行都被我们修改了,那么我们就可以将这幅图抽象成两条数轴上的操作。
对于每一次的修改,我们只需要单点修改某一个节点上的数。
但是这个节点上需要记录什么信息呢?这种题目很明显用线段树维护比较好(树状数组也很好,但是我还是喜欢线段树),那么要节点要记录的数值有\(l\),和\(r\),除此之外,我们需要知道在这一段区间中,被红雾所覆盖的节点的总数。
然后单点修改就到这里位置。
关于查询操作,我们每次是查询两个线段树的区间和。
我们假设求出求出来的值分别是\(ansx\)和\(ansy\),对于的分别是\(x\)轴上的答案和\(y\)轴上的答案。
然后在定义\(lenx\)和\(leny\)表示查找区间\(x\)的长度和和\(y\)区间的长度。
因为我们知道,两个红雾重合在一起就会被抵消掉,也就是说在查找区间内,所有的\(ansx\)和所有\(ansy\)全都会重合。 为什么?因为每一次修改就一定是修改到底。
那么我们通过容斥原理,如果仅算\(x\)的答案就是\(ansy*x\),也就是当前\(x\)数×有的\(y\),同理\(y\)的答案是\(ansx*y\),但是有消除,所以我们需要\(-\)掉\(2*ansx*ansy\),为什么是\(2*ansx*ansy\),而不是\(ansx*ansy\),因为你不是在去掉重复,而是减掉消除的部分。
ac代码
#include<bits/stdc++.h>
#define LL long long
#define N 100005
using namespace std;
int read(){
int w=0,x=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
int n,m,q;
struct segment_tree{
#define ls (nod<<1)
#define rs (nod<<1|1)
#define mid ((l+r)>>1)
struct node{
int l,r;
LL s;
}tr[N<<2];
void pushup(int nod){tr[nod].s=tr[ls].s+tr[rs].s;}
void build(int l,int r,int nod){
tr[nod].l=l; tr[nod].r=r; tr[nod].s=0;
if(l==r) return;
build(l,mid,ls);
build(mid+1,r,rs);
}
void update_point(int nod,int k){
int l=tr[nod].l,r=tr[nod].r;
if(l==r){tr[nod].s^=1;return;}
if(k<=mid) update_point(ls,k);
else update_point(rs,k);
pushup(nod);
}
LL query_sec(int nod,int ql,int qr){
int l=tr[nod].l,r=tr[nod].r;
if(ql<=l&&r<=qr) return tr[nod].s;
LL res=0;
if(ql<=mid) res+=query_sec(ls,ql,qr);
if(qr>mid) res+=query_sec(rs,ql,qr);
return res;
}
}tr1,tr2;
int main(){
n=read(),m=read(),q=read();
tr1.build(1,n,1); tr2.build(1,m,1);
while(q--){
int opt=read();
if(opt==1){
int x=read(),y=read();
tr1.update_point(1,x); tr2.update_point(1,y);
}
else{
#define x1 saber
#define x2 archer
#define y1 caster
#define y2 rider
int x1=read(),y1=read(),x2=read(),y2=read();
LL a1=tr1.query_sec(1,x1,x2),a2=tr2.query_sec(1,y1,y2);
LL ans=a1*(LL)(y2-y1+1)+a2*(LL)(x2-x1+1)-a1*a2*2;
printf("%lld\n",ans);
}
}
return 0;
}
对于自己代码的感想
因为\(y1\)成为了关键字,那么就重定义一下(我是一个\(Fate\)迷)QAQ。
[luogu3801]红色的幻想乡的更多相关文章
- AC日记——红色的幻想乡 洛谷 P3801
红色的幻想乡 思路: 线段树+容斥原理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #de ...
- 洛谷——P3801 红色的幻想乡
P3801 红色的幻想乡 推荐阅读 https://blog.csdn.net/qq_41252892/article/details/79035942 非常清楚 线段树单点修改 emmm没什么了 # ...
- [luogu P3801] 红色的幻想乡 [线段树][树状数组]
题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一 ...
- 洛谷 P3801 红色的幻想乡
题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一 ...
- 洛谷p3801:红色的幻想乡
初见完全没有思路.....感觉像是线段树 但二维感觉完全不可做嘛 于是只能去看了看题解 然而还是疯狂爆零+WA.. 和yycc神犇调了两三个小时才调出来... ——————以下个人理解 考虑到每次的修 ...
- luogu P3801 红色的幻想乡
嘟嘟嘟 首先人人都能想到是线段树,不过二维线段树肯定会MLE+TLE的. 我们换一种想法,不去修改整个区间,而是修改一个点:开横竖两个线段树,分别记录哪些行和列被修改了.因为如果两阵红雾碰撞,则会因为 ...
- bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解
先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...
- BZOJ4596: [Shoi2016]黑暗前的幻想乡
Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖 怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类) 博丽灵梦和八云紫等人整日高谈所有妖怪 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1017 Solved: 599[Submit][S ...
随机推荐
- git 提交新增文件到网站
git add -A 是将所有的修改都提交.你可以用git status查看当前的变化,然后通过git add xxx有选择的提交.git commit 是将变化先提交到本地.git commit - ...
- tensorflow笔记:多层LSTM代码分析
tensorflow笔记:多层LSTM代码分析 标签(空格分隔): tensorflow笔记 tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) ten ...
- Scala学习(六)---Scala对象
Scala中的对象 摘要: 在本篇中,你将会学到何时使用Scala的object语法结构.在你需要某个类的单个实例时,或者想为其他值或函数找一个可以挂靠的地方时,你就会用到它.本篇的要点包括: 1. ...
- FFMPEG指令
FFmpeg是一个用于音视频处理的自由软件,被广泛用于音视频开发.FFmpeg功能强大,本文主要介绍如何使用FFmpeg命令行工具进行简单的视频处理. 安装FFmpeg可以在官网下载各平台软件包或者静 ...
- 领跑衫获奖感言 & 课程总结
很荣幸在最后一次课获得了黄色领跑衫.在此,我要感谢教师杨贵福,感谢<构建之法>的作者邹欣老师和出版人周筠老师,感谢“耐撕”团队的队员们. 作为旁听生,最后一堂课,有些不舍.不多说,先上图, ...
- C#【结对编程作业】小学数学习题助手
一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...
- Leetcode——58.最后一个单词的长度
给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指由字母组成,但不包含任何空格的字符串. 示例: 输入: &quo ...
- 01springboot快速入门
SpringBoot快速入门 springboot的宗旨是习惯大于配置,所以spring里面大量使用了默认的配置来简化spring的配置.spring Boot的主要优点: 为所有Spring开发者更 ...
- java 值传递 数组传递
在java中,不允许程序员选择值传递还是地址传递各个参数,基本类型总是按值传递.对于对象来说,是将对象的引用也就是副本传递给了方法,在方法中只有对对象进行修改才能影响该对象的值,操作对象的引用时是无法 ...
- POI (Apache POI)
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. 基本功能 编辑 结构: HSSF - 提供读写Mi ...