【洛谷】【线段树+位运算】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 ...
随机推荐
- SQL Server Profiler小技巧——筛选请求
如果需要转载,请附上本文作者和原文链接:http://www.cnblogs.com/zeusro/p/4016228.html Microsoft SQL Server Profiler 是 SQL ...
- 【转】maven profile实现多环境打包
作为一名程序员,在开发的过程中,经常需要面对不同的运行环境(开发环境.测试环境.生产环境.内网环境.外网环境等等),在不同的环境中,相关的配置一般不一样,比如数据源配置.日志文件配置.以及一些软件运行 ...
- Docker(一):入门教程
2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业. 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文就来详细解释,帮助大家理解它,还带有简单 ...
- Python手写模拟单向链表对象,栈对象和树
单向链表: class error(Exception): def __init__(self,msg): super(error,self).__init__() self.msg=msg def ...
- 177. [USACO Jan07] 有限制的素数
177. [USACO Jan07] ★ 输入文件:qprime.in 输出文件:qprime.out 简单对比 时间限制:1 s 内存限制:128 MB Farmer John 开始 ...
- 从零开始学习html(四)认识标签(第三部分)
一.使用<a>标签,链接到另一个页面 <!DOCTYPE HTML> <html> <head> <meta http-equiv="C ...
- python函数之调用函数
调用函数 python中内置了许多函数,我们可以直接调用,但需要注意的是参数的个数和类型一定要和函数一致,有时候不一致时,可以进行数据类型转换 1.abs()函数[求绝对值的函数,只接受一个参数] # ...
- L3(SP+OO+UT)能力评估
- ew代理实战
前言 渗透内网代理必不可少,本文做个记录 正文 工具下载地址 http://rootkiter.com/EarthWorm/ ssocksd开启 socks5 代理 环境 代理:192.168.211 ...
- windows 2008 r2 安装 owas 2013
windows 2008 r2 安装 owas 2013 1.NDP452-KB2901907-x86-x64-AllOS-ENU 2.Add-WindowsFeature Web-Server,W ...