原题链接

前置知识:

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

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

  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. CentOS7使用firewalld管理防火墙与端口

    firewalld的基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status fir ...

  2. iOS多线程开发之GCD(死锁篇)

    上篇和中篇讲解了什么是GCD,如何使用GCD,这篇文章将讲解使用GCD中将遇到的死锁问题.有兴趣的朋友可以回顾<iOS多线程开发之GCD(上篇)>和<iOS多线程开发之GCD(中篇) ...

  3. 新财报再次巨亏 HTC还能活到2017吗?

    HTC还能活到2017吗?" title="新财报再次巨亏 HTC还能活到2017吗?"> 当下智能手机行业虽然竞争惨烈,但也称得上是精彩纷呈:性能.外形不断进化, ...

  4. NEWMING

    这里只是列举一些常用的文件操作命令. cd 跳转切换目录 # 格式:cd dirname 比如在打开用户主目录盘下的 myidoc 文件夹 cd ~/myidoc 跳转到当前目录的上一级 cd ../ ...

  5. JAVA如何判断两个字符串是否相等

    ==比较引用,equals 比较值 1.java中字符串的比较:== 我们经常习惯性的写上if(str1==str2),这种写法在java中可能会带来问题 example1: String a=&qu ...

  6. 利用FinalData恢复shift+delete误删的文件

    当前位置 : 首页 » 文章分类 :  生活  »  利用FinalData恢复shift+delete误删的文件 上一篇 有关可变形部件模型(Deformable Part Model)的一些说明 ...

  7. 致歉Note7用户后,三星要还给世界下一个机皇

    ​ 1月23日,三星电子在韩国首尔公布了Note7事件原因调查结果.此次认定过程精密而繁琐,最终结果发布距离三星宣布全球召回Note7已经有3个月. 相比事发之初各路信息甚嚣尘上,现在虽然还不能说已经 ...

  8. PyCharm+git+码云实现project版本控制

    1.安装git https://git-scm.com/downloads 2.PyCharm中配置 3.申请码云 4.PyCharm中安装码云插件 右键选择,重启Pycharm. 重新打开PyCha ...

  9. 小技巧(一):将文本文件txt或网页快捷方式固定到win10开始菜单

    win10不知道怎么回事不支持将文本文件和网页快捷方式固定到开始菜单 解决方法: 利用cmd 创建一个快捷方式: 路径:cmd /A /C  C:\Users\Admin\Desktop\test.t ...

  10. 从头认识js-js的发展历史

    JavaScript简介 JavaScript诞生于1995年,当时,它的主要目的是处理以前有服务端语言(如Perl)负责的一些输入验证操作. JavaScript简史 1995年2月当时就职于Net ...