原题链接

前置知识:

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

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

  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. android编译架构之添加C项目

    1.  增加一个项目与android编译中枢息息相关.特别需要告诉编译中枢的一些特别信息. 例如: A 这个项目target名字是什么 B 这个项目编译类型是什么,bin?c?lib?or jar? ...

  2. 在 React Native 中使用 moment.js 無法載入語系檔案

    moment.js 是很常見的日期時間 library,友善的 API 與極佳的執行效率是它的兩大賣點.例如 (new Date()).getFullYear(),如果使用 moment.js 我可以 ...

  3. C++走向远洋——34(友元函数,成员函数和一般函数的区别)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:youyuan.cpp * 作者:常轩 * 微信公众号:Worl ...

  4. Redis list实现原理 - 双向循环链表

    双向链表 双向表示每个节点知道自己的直接前驱和直接后继,每个节点需要三个域 查找方向可以是从左往右也可以是从右往左,但是要实现从右往左还需要终端节点的地址,所以通常会设计成双向的循环链表; 双向的循环 ...

  5. PyQt5之音乐播放器

    按照自己思路简单写了个桌面播放器,只有自己喜欢的歌.使用QtDesigner设计的ui界面,功能简单,还有很多bug@~@,代码奉上: music_button.ui使用扩展工具pyuic5生成了mu ...

  6. PyQt5之QtMultimedia模块音乐播放没声音已解决

    昨天用PyQt5的QtMultimedia模块播放音乐时,单独使用可播放,放代码里结合使用死的播放不了.以下是测试demo可播放代码: # -*- coding: utf-8 -*- # Nola f ...

  7. 大厂面试官问你META-INF/spring.factories要怎么实现自动扫描、自动装配?

    大厂面试官问你META-INF/spring.factories要怎么实现自动扫描.自动装配?   很多程序员想面试进互联网大厂,但是也有很多人不知道进入大厂需要具备哪些条件,以及面试官会问哪些问题, ...

  8. 某图片站反爬加密字段x-api-key破解

    前言 此次逆向的是某“你们都懂”领域的图片站,目前此站限制注册,非会员无法访问:前两天偶然搞到了份邀请码,进入后发现质量还可以,于是尝试爬取,在爬虫编写过程中发现此站点采用了不少手段来阻止自动化脚本( ...

  9. Linux centos7.0 配置防火墙及开放端口

    现在防火墙有两种服务1.service firewalld 2.service iptables 一.就firewalld来说查看开放的端口  netstat  -anp 查询防火墙状态  servi ...

  10. 关于HTTP那些事

    写这篇文章的原因 记录前端性能优化用到的关键概念 简化大家对HTTP的学习 大家或许面试的时候可以用得到哦 HTTP是什么 Web的应用层协议(超文本传输协议HyperText Transfer Pr ...