题解 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 & ...
随机推荐
- python 另一种打开文章的方式——codecs
通常我们使用python打开文件都是 open(‘beijing.txt’)或者是 with open(‘beijing.txt’)as f 那么今天来给你带来一个新的文档打开方式 python的co ...
- 没听说过这些,就不要说你懂并发了,two。
引言 为了更加形象的描述并发的基础知识,因此本文LZ采用了园子里一度大火的标题形式——“没听说过XXXX,就不要说你XXXX了”.希望能够给猿友们一个醒目的警醒,借此来普及并发的基础知识,也讨论一下这 ...
- linux 查看服务器序列号
1.安装工具 dmidecode yum install dmidecode -y 2.使用 dmidecode -t 1
- 六大iT公司的组织结构
- 搭建好看的静态博客(使用Hexo进行搭建)
经常看到大牛的博客非常的高大帅气,虽然我很渣,但是逼格不能输,所以有了以下的搭建记录. 我的成果ninwoo,喜欢的可以参考下面的记录一起来动手搞起来. 安装Git Bash 访问git下载最新版本的 ...
- 【python 3.6】类:访问属性及调用方法
>>> class price(): //定义1个类,用于计算价格 def __init__(self,name,danjia): //初始化方法,定义商品名称和单价 self.na ...
- 比较语义分割的几种结构:FCN,UNET,SegNet,PSPNet和Deeplab
简介 语义分割:给图像的每个像素点标注类别.通常认为这个类别与邻近像素类别有关,同时也和这个像素点归属的整体类别有关.利用图像分类的网络结构,可以利用不同层次的特征向量来满足判定需求.现有算法的主要区 ...
- 笨办法学Python - 习题4: Variables and Names
1.习题 4: 变量(variable)和命名 学习目标:了解Python中变量的定义,学习定义简明易记的变量名 变量:变量是存储内存中的值,就是每定义一个变量就会在内存中开辟一个空间.基于变量的类型 ...
- 在Gulp中使用BrowserSync
博客已迁移至http://zlwis.me. 很早就听说过BrowserSync,也看过一些相关文章,可就是没用过.之前一直在用Gulp开发项目,每次编写完Sass后还要用按F5刷新页面看效果,想想也 ...
- 王者荣耀交流协会final发布-第一次scrum立会
1.例会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐 master:袁玥 2.时间跨度 2017年12月1日 17:00 — 17:31,总计31分钟 3.地点 一食堂二楼沙发座椅 ...