这个题我愣是交了好几遍没有过......

后来@_皎月半洒花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]开关】的更多相关文章

  1. 洛谷 P3870 [TJOI2009]开关 题解

    原题链接 前置知识: 线段树的单点.区间的修改与查询. 一看,我们需要维护两个操作: 区间取反: 区间求和. (因为区间 \(1\) 的个数,就是区间的和) 典型的 线段树 . 如果你只会线段树的 区 ...

  2. 洛谷 P3870 [TJOI2009]开关

    题意简述 有n盏灯,默认为关,有两个操作: 1.改变l~r的灯的状态(把开着的灯关上,关着的灯打开) 2.查询l~r开着的灯的数量 题解思路 维护一个线段树,支持区间修改,区间查询 懒标记每次^1 代 ...

  3. P3870 [TJOI2009]开关

    思路 重题 代码 #include <iostream> #include <vector> #include <cstdio> #include <cstr ...

  4. 洛谷P3870 [TJOI2009]开关

    题目描述 现有\(N(2 ≤ N ≤ 100000)\)盏灯排成一排,从左到右依次编号为:\(1,2,......,N\).然后依次执行\(M(1 ≤ M ≤ 100000)\)项操作,操作分为两种: ...

  5. 洛谷P3870 [TJOI2009] 开关 (线段树)

    简单的省选题...... 打异或标记即可. 1 #include<bits/stdc++.h> 2 const int N=2e5+10; 3 using namespace std; 4 ...

  6. 题解 P3870 【[TJOI2009]开关】/基础分块学习小结

    直接进入正题: 分块: 分块分块,就是把一个长串东西,分为许多块,这样,我们就可以在操作一个区间的时候,对于在区间里面完整的块,直接操作块,不完整的直接操作即可,因为不完整,再加上一个块本身就不大,复 ...

  7. 洛谷 3870 [TJOI2009]开关

    [题解] 线段树基础题.对于每个修改操作把相应区间的sum改为区间长度-sum即可. #include<cstdio> #include<algorithm> #include ...

  8. [TJOI2009]开关 (线段树)

    题目描述 现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N.然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[ ...

  9. Luogu3870 [TJOI2009]开关 (分块)

    线段树做法很简单,但分块好啊 #include <iostream> #include <cstdio> #include <cstring> #include & ...

随机推荐

  1. linux 查看服务器序列号

    1.安装工具 dmidecode yum install dmidecode -y 2.使用 dmidecode -t  1

  2. hdu1232畅通工程(并查集,简单题)

    传送门 最少好要修多少条路太能使全部城镇连通.只要用并查集算可以连通的城市的组数,修的路就是组数减1 #include<bits/stdc++.h> using namespace std ...

  3. 180804-Spring之动态注册bean

    Spring之动态注册bean 什么场景下,需要主动向Spring容器注册bean呢? 如我之前做个的一个支持扫表的基础平台,使用者只需要添加基础配置 + Groovy任务,就可以丢到这个平台上面来运 ...

  4. python自编程序实现——robert算子、sobel算子、Laplace算子进行图像边缘提取

    实现思路: 1,将传进来的图片矩阵用算子进行卷积求和(卷积和取绝对值) 2,用新的矩阵(与原图一样大小)去接收每次的卷积和的值 3,卷积图片所有的像素点后,把新的矩阵数据类型转化为uint8 注意: ...

  5. 监控与管理-SpringBoot

    在微服务架构中,我们将原本庞大的单体系统拆分成多个提供不同服务的应用. 虽然 各个应用的内部逻辑因分解而得以简化,但是由于部署应用的数量成倍增长,使得系统的 维护复杂度大大提升. 对于运维人员来说,随 ...

  6. Selenium笔记:PO模型

    所有用到的页面都定义成一个类,继承自基础的Page类 把页面中用到的元素定义成方法 把页面上一些操作定义成方法

  7. Ubuntu下LimeSDR Mini使用说明

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 LimeSDR链接:https://item.taobao.com/item.htm?spm=a230r.1 ...

  8. php从入门到放弃系列-03.php函数和面向对象

    php从入门到放弃系列-03.php函数和面向对象 一.函数 php真正的威力源自它的函数,内置了1000个函数,可以参考PHP 参考手册. 自定义函数: function functionName( ...

  9. Python学习之路目录(收藏整理)

    目录 Python之路[第一篇]:Python简介和入门 Python之路[第二篇]:Python基础(一) Python之路[第三篇]:Python基础(二) Python之路[第四篇]:模块    ...

  10. Geatpy遗传算法在曲线寻优上的初步探究

    园子里关于遗传算法的教案不少,但基于geatpy框架的并未多见,故分享此文以作参考,还望广大园友多多指教! Geatpy出自三所名校联合团队之手,是遗传算法领域的权威框架(python),其效率之高. ...