题解 P3870 【[TJOI2009]开关】
这个题我愣是交了好几遍没有过......
后来@_皎月半洒花dalao告诉我说要^儿子节点的tag,然后就明白了......
行吧,先上题面:
题目描述
现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N。然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间
[a, b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开),第二种操作是指定一个区间[a, b],要求你输出这个区间内有多少盏灯是打开的。灯在初始时都是关着的。输入输出格式
输入格式:
第一行有两个整数N和M,分别表示灯的数目和操作的数目。接下来有M行,每行有三个整数,依次为:c, a, b。其中c表示操作的种类,当c的值为0时,表示是第一种操作。当c的值为1时表示是第二种操作。a和b则分别表示了操作区间的左右边界(1 ≤ a ≤ b ≤ N)。
输出格式:
每当遇到第二种操作时,输出一行,包含一个整数:此时在查询的区间中打开的灯的数目。
这个题比较水有好处的一点是有很多题都和这个题基本一样。
然后我们看到这个题让我们统计一个线段内的某一种和和修改区间:
线段树啊!
然后我就把校门外的树的代码扒过来了......
评测记录
后果:听取WA声一片。
为啥呢?
因为儿子节点有可能比父亲节点提前改过了。
所以我们只能取反,把原先的状态反过来。
然后就成了提交记录
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=100001;
struct tree{
int l,r,flash,dark;
bool tag;
}segment[maxn<<2];
int n,m;
inline void update(int rt);
inline void pushdown(int rt);
inline void build_tree(int rt,int l,int r);
inline int query(int rt,int l,int r);
inline void modify(int rt,int l,int r);
int main()
{
cin>>n>>m;
build_tree(1,1,n);
while (m--)
{
char flag;
int l,r;
cin>>flag>>l>>r;
if (flag=='0')modify(1,l,r);
else cout<<query(1,l,r)<<'\n';
}
return 0;
}
inline void update(int rt)
{
int lson=rt<<1,rson=lson+1;
segment[rt].flash=segment[lson].flash+segment[rson].flash;
segment[rt].dark=segment[lson].dark+segment[rson].dark;
}
inline void pushdown(int rt)
{
int lson=rt<<1,rson=lson+1;
segment[lson].tag^=1;
segment[rson].tag^=1;
swap(segment[lson].dark,segment[lson].flash);
swap(segment[rson].dark,segment[rson].flash);
segment[rt].tag^=1;
}
inline void build_tree(int rt,int l,int r)
{
segment[rt].l=l,segment[rt].r=r;
if (l==r)
{
segment[rt].flash=0;
segment[rt].dark=1;
segment[rt].tag=false;
return;
}
int mid=(r+l)>>1,lson=rt<<1,rson=lson+1;
build_tree(lson,l,mid);
build_tree(rson,mid+1,r);
update(rt);
}
inline void modify(int rt,int l,int r)
{
if (segment[rt].l<=l&&segment[rt].r>=r)
{
if (segment[rt].l==l&&segment[rt].r==r)
{
segment[rt].tag^=1;
swap(segment[rt].flash,segment[rt].dark);
return;
}
if (segment[rt].tag)pushdown(rt);
int mid=(segment[rt].l+segment[rt].r)>>1,lson=rt<<1,rson=lson+1;
if (r<=mid)modify(lson,l,r);
else if (l>mid)modify(rson,l,r);
else
{
modify(lson,l,mid);
modify(rson,mid+1,r);
}
update(rt);
}
return ;
}
inline int query(int rt,int l,int r)
{
if (segment[rt].l<=l&&segment[rt].r>=r)
{
if (segment[rt].l==l&&segment[rt].r==r)
{
return segment[rt].flash;
}
if (segment[rt].tag)pushdown(rt);
int mid=(segment[rt].l+segment[rt].r)>>1,lson=rt<<1,rson=lson+1;
if (r<=mid)return query(lson,l,r);
else if (l>=mid+1)return query(rson,l,r);
else return query(lson,l,mid)+query(rson,mid+1,r);
}
return 0;
}
行吧......
题解 P3870 【[TJOI2009]开关】的更多相关文章
- 洛谷 P3870 [TJOI2009]开关 题解
原题链接 前置知识: 线段树的单点.区间的修改与查询. 一看,我们需要维护两个操作: 区间取反: 区间求和. (因为区间 \(1\) 的个数,就是区间的和) 典型的 线段树 . 如果你只会线段树的 区 ...
- 洛谷 P3870 [TJOI2009]开关
题意简述 有n盏灯,默认为关,有两个操作: 1.改变l~r的灯的状态(把开着的灯关上,关着的灯打开) 2.查询l~r开着的灯的数量 题解思路 维护一个线段树,支持区间修改,区间查询 懒标记每次^1 代 ...
- P3870 [TJOI2009]开关
思路 重题 代码 #include <iostream> #include <vector> #include <cstdio> #include <cstr ...
- 洛谷P3870 [TJOI2009]开关
题目描述 现有\(N(2 ≤ N ≤ 100000)\)盏灯排成一排,从左到右依次编号为:\(1,2,......,N\).然后依次执行\(M(1 ≤ M ≤ 100000)\)项操作,操作分为两种: ...
- 洛谷P3870 [TJOI2009] 开关 (线段树)
简单的省选题...... 打异或标记即可. 1 #include<bits/stdc++.h> 2 const int N=2e5+10; 3 using namespace std; 4 ...
- 题解 P3870 【[TJOI2009]开关】/基础分块学习小结
直接进入正题: 分块: 分块分块,就是把一个长串东西,分为许多块,这样,我们就可以在操作一个区间的时候,对于在区间里面完整的块,直接操作块,不完整的直接操作即可,因为不完整,再加上一个块本身就不大,复 ...
- 洛谷 3870 [TJOI2009]开关
[题解] 线段树基础题.对于每个修改操作把相应区间的sum改为区间长度-sum即可. #include<cstdio> #include<algorithm> #include ...
- [TJOI2009]开关 (线段树)
题目描述 现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N.然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[ ...
- Luogu3870 [TJOI2009]开关 (分块)
线段树做法很简单,但分块好啊 #include <iostream> #include <cstdio> #include <cstring> #include & ...
随机推荐
- CobarClient源码分析
CobarClient是阿里巴巴公司开发一个的开源的.基于iBatis和Spring的分布式数据库访问层.为了支持iBatis,Spring框架提供了一个SqlMapClientTemplate,通过 ...
- SpringBoot日记——SpringMvc自动配置与扩展篇
为了让SpringBoot保持对SpringMVC的全面支持和扩展,而且还要维持SpringBoot不写xml配置的优势,我们需要添加一些简单的配置类即可实现: 通常我们使用的最多的注解是: @Bea ...
- JAVA使用qrcode生成二维码(带logo/不带logo)
/** * */ package qrcode; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; i ...
- 树莓派修改VNC分辨率
1.打开终端输入 sudo raspi-config 2. 选择 Advanced Options 再选择 Resolution 3.选择想要的分辨率,确定 4.重启
- Window10家庭版启动hyper-v虚拟机组件
在安装docker的时候发现如果直接使用docker for windows,对系统的要求是window10专业版或企业版,家庭版本身没有hyper-v,不能支持 虚拟化.但是后来我在搜索过程中发现, ...
- 2.4 Oracle之DCL的SQL语句之用户权限以及三大范式
DCL (Data Control Language,数据库控制语言)用于定义数据库权限 一.用户权限 1.1 建立用户以及授权: Eg :CREATE USER 用户名 IDENTIFIED ...
- 【读书笔记】《Computer Organization and Design: The Hardware/Software Interface》(1)
笔记前言: <Computer Organization and Design: The Hardware/Software Interface>,中文译名,<计算机组成与设计:硬件 ...
- python-python爬取豆果网(菜谱信息)
#-*- coding = utf-8 -*- #获取豆果网图片 import io from bs4 import BeautifulSoup import requests #爬取菜谱的地址 ur ...
- 论文笔记:分形网络(FractalNet: Ultra-Deep Neural Networks without Residuals)
FractalNet: Ultra-Deep Neural Networks without Residuals ICLR 2017 Gustav Larsson, Michael Maire, Gr ...
- Erlang的调度原理(译文)
原文 http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html 免爬墙链接 http://www.diku ...