原题链接

前置知识:

线段树的单点、区间的修改与查询。

一看,我们需要维护两个操作:

  1. 区间取反;

  2. 区间求和。

(因为区间 \(1\) 的个数,就是区间的和)

典型的 线段树

如果你只会线段树的 区间修改,单点修改,区间查询,单点查询 的话,这题的 “取反” 是个难题。

但是,这个数组有个性质:

\(a_i \in {0,1}\)

也就是说,假设一个数组一开始这样子:

\(1\) \(2\) \(3\) \(4\)
\(a_i\) \(0\) \(1\) \(0\) \(0\)
\(b_i\) \(1\) \(0\) \(1\) \(1\)

翻转过后,你会发现:

翻转后的区间和 = 区间长度 - 区间和。

因为 原来的区间和 是 \(1\) 的个数,减掉 \(1\) 的个数就是 \(0\) 的个数,而 \(0\) 翻转后就是 \(1\),会对答案产生贡献。

下面区间翻转的标记叠加怎么办?

显然,翻转 偶数 次直接变成 \(0\),因为等于没有翻转;翻转 奇数 次变成 \(1\),因为等于翻转 \(1\) 次。

那么,每次翻转在标记上 异或 一下就行。

(异或之后,\(0 \gets 1\),\(1 \gets 0\))

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; const int N=1e5+1;
#define L (i<<1)
#define R (i<<1)+1 inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} struct tree{
int l,r,sumi;
int tag;
};
tree t[N<<2];
int n,m; inline void update(int i) {
t[i].sumi=t[L].sumi+t[R].sumi;
} inline void build_tree(int i,int l,int r) {
t[i].l=l; t[i].r=r; t[i].tag=0; t[i].sumi=0;
if(l==r) return; int mid=(l+r)>>1;
build_tree(L,l,mid);
build_tree(R,mid+1,r);
} //建树 inline void pushdown(int i) {
int x=t[i].tag; if(!x) return;
t[L].sumi=t[L].r-t[L].l+1-t[L].sumi;
t[R].sumi=t[R].r-t[R].l+1-t[R].sumi;
t[L].tag^=1; t[R].tag^=1; t[i].tag=0;
} //下传标记 inline void change(int i,int l,int r) {
if(l<=t[i].l && t[i].r<=r) {
t[i].sumi=t[i].r-t[i].l+1-t[i].sumi;
t[i].tag^=1; return;
} pushdown(i); int mid=(t[i].l+t[i].r)>>1;
if(l<=mid) change(L,l,r);
if(r>mid) change(R,l,r);;
update(i);
} //区间修改 inline int query(int i,int l,int r) {
if(l<=t[i].l && t[i].r<=r) return t[i].sumi;
pushdown(i); int mid=(t[i].l+t[i].r)>>1,ans=0;
if(l<=mid) ans+=query(L,l,r);
if(r>mid) ans+=query(R,l,r);
return ans;
} //区间询问 int main(){
n=read(); m=read();
build_tree(1,1,n);
while(m--) {
int opt=read(),l=read(),r=read();
if(!opt) change(1,l,r);
else printf("%d\n",query(1,l,r));
}
return 0;
}

洛谷 P3870 [TJOI2009]开关 题解的更多相关文章

  1. 洛谷P3870 [TJOI2009]开关

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

  2. 洛谷 P3870 [TJOI2009]开关

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

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

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

  4. 洛谷 3870 [TJOI2009]开关

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

  5. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  6. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  7. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  8. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  9. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

随机推荐

  1. JAVA SE Lesson 1

    1.  类是一种抽象的概念,对象是类的一种具体表示形式,是具体的概念.先有类,然后由类来生成对象(Object).对象又叫做实例(Instance).2.  类由两大部分构成:属性以及方法.属性一般用 ...

  2. react render渲染的几种情况

    1. 首次加载 2. setState改变组件内部state. 注意: 此处是说通过setState方法改变. 3. 接受到新的props

  3. ERROR: Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 31, event_type: 35报错处理

    centos7系统MySQL5.7在用mysqlbinlog命令查询binlog日志时刚开始查询即自动终止查询,查了一下该日志有300M,于是仔细看发现有报错,见下图: 在网上查找经验贴http:// ...

  4. Tian Tian 菾菾 导游 陪同

    自画像系列是梵高的代表作之一,他是一位自学成才的画家,下笔完全自由,主观提取了当时印象派画家学到的技巧,在这幅画中,我们可以看到,颜色在画中的堆叠,色彩与笔在画中表现的形态,都表现出,梵高在他作画中内 ...

  5. 从5个经典工作开始看语义SLAM

    本文试图概括Semantic SLAM的主要思路和近年工作,⻓期更新.但因水平有限,若有错漏,感谢指正. (更好的公式显示效果,可关注文章底部的公众号) Semantic SLAM 简介 至今为止,主 ...

  6. 如何在自己的CSDN博客中增添【高大上】的博客栏目?

    前几天看到过一位博主的博客界面,向下看 ☟ (博主对不起啊!把你的公众号给抹了~~~),感觉做这个东西挺好玩的,而且我竟然找不到在哪个地方可以设置!在百度上也没有搜到教程,最后问了一下贺老师知道了入口 ...

  7. #2020.1.26笔记——springdatajpa

    2020.1.26笔记--springdatajpa 使用jpa的步骤: 1. 导入maven坐标 <?xml version="1.0" encoding="UT ...

  8. java网络编程——socket实现简单的CS会话

    还记得当年学计网课时用python实现一个简单的CS会话功能,这也是学习socket网络编程的第一步,现改用java重新实现,以此记录. 客户端 import java.io.*; import ja ...

  9. scrapy-redis分布式爬取知乎问答,使用docker布置多台机器。

    先上结果: 问题: 答案: 可以看到现在答案文档有十万多,十万个为什么~hh 正文开始: 分布式爬虫应该是在多台服务器(A B C服务器)布置爬虫环境,让它们重复交叉爬取,这样的话需要用到状态管理器. ...

  10. 机器学习实用案例解析(1) 使用R语言

    简介 统计学一直在研究如何从数据中得到可解释的东西,而机器学习则关注如何将数据变成一些实用的东西.对两者做出如下对比更有助于理解“机器学习”这个术语:机器学习研究的内容是教给计算机一些知识,再让计算机 ...