[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 ...
随机推荐
- DataWorks使用小结(二)——功能面板使用指南
一.数据开发 1.任务开发 新建表 野路子可以直接新建一个任务,粘贴DDL,手动运行任务即可完成建表 正常应当是在“数据管理”->数据表管理中建表: 支持可视化建表和DDL建表(配合之前的宏,建 ...
- 【强化学习】python 实现 q-learning 例五(GUI)
本文作者:hhh5460 本文地址:https://www.cnblogs.com/hhh5460/p/10143579.html 感谢pengdali,本文的 class Maze 参考了他的博客, ...
- supervisord监控服务必备命令
supervisord(http://supervisord.org/introduction.html)是一个非常优秀的进程管理工具,使用Python开发.它可以在类UNIX系统的方式让用户来准确地 ...
- haproxy反向代理环境部署(http和https代理)
操作背景:前方有一台haproxy代理机器(115.100.120.57/192.168.1.7),后方两台realserver机器(192.168.1.150.192.168.1.151,没有公网i ...
- FormData
1. 概述FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利. 2. 构造函数创建一个formData对象 ...
- Linux常用指令【转载】
[收藏]Linux常用指令[转载] $ 命令行提示符 粗体表示命令 斜体表示参数 filename, file1, file2 都是文件名.有时文件名有后缀,比如file.zip command 命令 ...
- Pair Project 1 elevator
结对编程——电梯调度 12061181 高孟烨 12061182 郝倩 1.结对编程的优缺点: 优点:结对编程可以结合两个人各自擅长之地,充分发挥两个人各自的优势,两个人一起合作效率会更高.一份工作两 ...
- 《Linux内核分析》第六周学习小结
进程的描述和进程的创建 一.进程的描述 进程描述符task_struct数据结构: (1)操作系统的三大功能: 进程管理.内存管理.文件系统 (2)进程的作用: 将信号.进程间通信.内存管理和文件系统 ...
- Hibernate_core_method
/** * Created by Administrator on 2015/11/30. *HibernateUtil */public class HibernateUtil { private ...
- squid反向代理
反向代理的作用是就爱那个网站中的静态自原本地化.也就是将一部分本应该有原是服务器处理的请求交给 Squid 缓存服务处理 编辑 Squid 服务程序的配置文件*(正向代理与反向代理不能同时使用,) ...