【洛谷】【线段树+位运算】P2574 XOR的艺术
【题目描述:】
AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏。在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下
1、 拥有一个伤害串为长度为n的01串。
2、 给定一个范围[l,r],伤害为伤害串的这个范围内中1的个数
3、 会被随机修改伤害串中的数值,修改的方法是把[l,r]中的所有数xor上1
AKN想知道一些时刻的伤害,请你帮助他求出这个伤害
【输入格式:】
第一行两个数n,m,表示长度为n的01串,有m个时刻
第二行一个长度为n的01串,为初始伤害串
第三行开始m行,每行三个数p,l,r
若p为0,则表示当前时刻改变[l,r]的伤害串,改变规则如上
若p为1,则表示当前时刻AKN想知道[l,r]的伤害
【输出格式:】
对于每次询问伤害,输出一个数值伤害,每次询问输出一行
输入样例#: 输出样例#:
输入输出样例
【算法分析:】
对于xor 1运算,其实是把序列中的所有0变成1,把所有1变成0
所以一个区间xor 1之后的值就变成了"区间长度减去区间和"
而关于lazy-tag的修改也有一些需要注意的地方:
对于一个二进制数num,num ^ 1 ^ 1 = num
所以lazy-tag每次修改的时候需要xor 1:两次xor操作正好相互抵消,而不能单纯地把它变成1
【代码:】
//P2574 XOR的艺术
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = 2e5 + ; int n, m, a[MAXN];
struct Segment {
int sum;
bool tag;
}t[MAXN << ]; void Build(int o, int l, int r) {
if(l == r) t[o].sum = a[l];
else {
int mid = (l + r) >> ;
Build(o << , l, mid);
Build(o << |, mid + , r);
t[o].sum = t[o << ].sum + t[o << |].sum;
}
} inline void down(int o, int len) {
if(!t[o].tag) return;
t[o << ].sum = (len - (len >> )) - t[o << ].sum;
t[o << |].sum = (len >> ) - t[o << |].sum;
t[o << ].tag ^= ;
t[o << |].tag ^= ;
t[o].tag = ;
} int Query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return t[o].sum;
down(o, r - l + );
int mid = (l + r) >> ;
int ret = ;
if(ql <= mid) ret += Query(o << , l, mid, ql, qr);
if(qr > mid) ret += Query(o << |, mid + , r, ql, qr);
return ret;
} void Update(int o, int l, int r, int ul, int ur) {
if(ul <= l && r <= ur) {
t[o].sum = r - l + - t[o].sum;
t[o].tag ^= ;
}
else {
down(o, r - l + );
int mid = (l + r) >> ;
if(ul <= mid) Update(o << , l, mid, ul, ur);
if(ur > mid) Update(o << |, mid + , r, ul, ur);
t[o].sum = t[o << ].sum + t[o << |].sum;
}
} int main() {
scanf("%d%d", &n, &m);
for(int i=; i<=n; ++i)
scanf("%1d", &a[i]);
Build(, , n);
while(m--) {
int fl, x, y;
scanf("%d%d%d", &fl, &x, &y);
if(!fl) Update(, , n, x, y);
else printf("%d\n", Query(, , n, x, y));
}
}
【 配套双倍经验题:】
1. P2846 [USACO08NOV]光开关Light Switching
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = 1e5 + ; int n, m;
struct Segment {
int sum;
bool tag;
}t[MAXN << ]; inline long long read() {
long long x = , f = ; char ch = getchar();
while(ch < '' || ch > '') {
if(ch == '-') f = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
x = (x << ) + (x << ) + ch - , ch = getchar();
return x * f;
} void Build(int o, int l, int r) {
if(l == r) t[o].sum = ;
else {
int mid = (l + r) >> ;
Build(o << , l, mid);
Build(o << |, mid + , r);
t[o].sum = t[o << ].sum + t[o << |].sum;
}
} inline void down(int o, int len) {
if(!t[o].tag) return;
t[o << ].sum = (len - (len >> )) - t[o << ].sum;
t[o << |].sum = (len >> ) - t[o << |].sum;
t[o << ].tag ^= ;
t[o << |].tag ^= ;
t[o].tag = ;
} void Update(int o, int l, int r, int ul, int ur) {
if(ul <= l && r <= ur) {
t[o].sum = r - l + - t[o].sum;
t[o].tag ^= ;
}
else {
down(o, r - l + );
int mid = (l + r) >> ;
if(ul <= mid) Update(o << , l, mid, ul, ur);
if(ur > mid) Update(o << |, mid + , r, ul, ur);
t[o].sum = t[o << ].sum + t[o << |].sum;
}
} int Query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return t[o].sum;
down(o, r - l + );
int mid = (l + r) >> ;
int ret = ;
if(ql <= mid) ret += Query(o << , l, mid, ql, qr);
if(qr > mid) ret += Query(o << |, mid + , r, ql, qr);
return ret;
} int main() {
n = read(), m = read();
Build(, , n);
while(m--) {
int fl = read(), x = read(), y = read();
if(fl) printf("%d\n", Query(, , n, x, y));
else Update(, , n, x, y);
}
}
光开关Light Switching
//[TJOI2009]开关
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = + ; int n, m; struct Segment {
int sum; bool tag;
}t[MAXN << ]; inline int read() {
int x=, f=; char ch=getchar();
while(ch<'' || ch>'') {
if(ch == '-') f = -;
ch = getchar();
}
while(ch>='' && ch<='')
x=(x<<) + (x<<) + ch-, ch = getchar();
return x * f;
} inline void down(int o, int len) {
if(!t[o].tag) return;
t[o << ].sum = (len - (len >> )) - t[o << ].sum;
t[o << |].sum = (len >> ) - t[o << |].sum;
t[o << ].tag ^= , t[o << |].tag ^= ;
t[o].tag = ;
} void Update(int o, int l, int r, int ul, int ur) {
if(ul <= l && r <= ur) {
t[o].sum = r - l + - t[o].sum;
t[o].tag ^= ;
}
else {
down(o, r - l + );
int mid = (l + r) >> ;
if(ul <= mid) Update(o << , l, mid, ul, ur);
if(ur > mid) Update(o << |, mid + , r, ul, ur);
t[o].sum = t[o << ].sum + t[o << |].sum;
}
} int Query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return t[o].sum;
down(o, r - l + );
int mid = (l + r) >> ;
int ret = ;
if(ql <= mid) ret += Query(o << , l, mid, ql, qr);
if(qr > mid) ret += Query(o << |, mid + , r, ql, qr);
return ret;
} int main() {
n = read(), m = read();
while(m--) {
int fl = read(), x = read(), y = read();
if(fl) printf("%d\n", Query(, , n, x, y));
else Update(, , n, x, y);
}
}
[TJOI2009]开关
【洛谷】【线段树+位运算】P2574 XOR的艺术的更多相关文章
- poj 3225 线段树+位运算
略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset 采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内U T S ← S ∪ T 即将[l, ...
- hdu 5023 线段树+位运算
主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位 ...
- poj 2777 Count Color - 线段树 - 位运算优化
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42472 Accepted: 12850 Description Cho ...
- Codeforces 620E New Year Tree(线段树+位运算)
题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...
- Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)
链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...
- Count Color(线段树+位运算 POJ2777)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 39917 Accepted: 12037 Descrip ...
- POJ 2777 Count Color(线段树+位运算)
题目链接:http://poj.org/problem?id=2777 Description Chosen Problem Solving and Program design as an opti ...
- poj_2777线段树+位运算
第一次没想到用位运算,不出意料的T了,,, PS:在床上呆了接近两个月后,我胡汉三又杀回来刷题啦-- #include<iostream> #include<cstdio> # ...
- [poj2777] Count Color (线段树 + 位运算) (水题)
发现自己越来越傻逼了.一道傻逼题搞了一晚上一直超时,凭啥子就我不能过??? 然后发现cin没关stdio同步... Description Chosen Problem Solving and Pro ...
随机推荐
- Es创建索引、设置和修改Mapping
Http接口操作示例如下: 1.创建索引: 2.删除索引: 3.创建mapping: 4.查看mapping:
- hdu 3295 模拟过程。数据很水
An interesting mobile game Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Ja ...
- HDU 3501 Calculation 2------欧拉函数变形
Calculation 2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- PyCharm 自定义模版
PyCharm 自定义模板 创建一个新的模板: 点击 Preferences... 选项或者按下快捷键 Command(⌘) + , 打开设置对话框. 找到 在 Editor 下的 File and ...
- JavaScript try-catch语句(错误处理)
错误处理在处理程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制.当然,大多数佼佼者确实做到了这一点,但通常只有服务器端应用程序才能做到如此.实际上,服务器端团队 ...
- 献给java求职路上的你们
为了更好的树立知识体系,我附加了相关的思维导图,分为pdf版和mindnote版.比如java相关的导图如下: 由于时间仓促,有些地方未写完,后面会继续补充.如有不妥之处,欢迎及时与我沟通. 相关概念 ...
- OpenGL学习--开发环境
1. VS2017 Professional安装 1.1. 下载 mu_visual_studio_professional_2017_x86_x64_10049787.exe 1.2. 双击开始安装 ...
- java jvm概述及工作过程中的内存管理
java jvm 有分层的思想. java类..java文件,源文件,源代码,源程序 编译器不能把源代码直接编译成0101,除非是java语言写的操作系统. windows认识的可执行文件 ...
- java 接口默认修饰符
概论: java接口可以是public 的,也可以是friendly的,但一定是abstracted的. java接口里的方法只能是public的.abstract的. java接口里的成员变量只能是 ...
- Python 操作数据库pymysql
import pymysql #添加数据 conn , user='root', passwd='', db='yyy') #更改获取数据结果的数据类型,默认是元组,可以改为字典等:#cursor=c ...