【题目描述:】

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

2.  P3870 [TJOI2009]开关

 //[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的艺术的更多相关文章

  1. poj 3225 线段树+位运算

    略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset 采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内U T S ← S ∪ T 即将[l, ...

  2. hdu 5023 线段树+位运算

    主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位 ...

  3. poj 2777 Count Color - 线段树 - 位运算优化

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42472   Accepted: 12850 Description Cho ...

  4. Codeforces 620E New Year Tree(线段树+位运算)

    题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...

  5. 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 ...

  6. Count Color(线段树+位运算 POJ2777)

    Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 39917 Accepted: 12037 Descrip ...

  7. POJ 2777 Count Color(线段树+位运算)

    题目链接:http://poj.org/problem?id=2777 Description Chosen Problem Solving and Program design as an opti ...

  8. poj_2777线段树+位运算

    第一次没想到用位运算,不出意料的T了,,, PS:在床上呆了接近两个月后,我胡汉三又杀回来刷题啦-- #include<iostream> #include<cstdio> # ...

  9. [poj2777] Count Color (线段树 + 位运算) (水题)

    发现自己越来越傻逼了.一道傻逼题搞了一晚上一直超时,凭啥子就我不能过??? 然后发现cin没关stdio同步... Description Chosen Problem Solving and Pro ...

随机推荐

  1. Android sdk manager 下载速度慢的问题

    不多说了,直接附上方法: 首先打开Ecplise 中Android sdk manager,打开后, 在此窗口的上方打开偏好设置选项,然后在里面设置HTTP Proxy server和HTTP Pro ...

  2. 求N的因子之和。

    理论依据: 代码: /* 显然,数据够大的时候,数组要用 __int64 */ #include<iostream> #include<map> #include<cst ...

  3. 思维导图(JavaScript基础)——温习一下下

  4. vue.js 开发环境配置

    1. node.js环境(npm包管理器) 下载: https://nodejs.org/en/download/current/ 下载解压版的方便 添加path环境后运行 npm包管理器,是集成在n ...

  5. Node.js从入门到实战ECMAScript6一页纸总结(很大的一页纸)

    一.ES5/ES6和babel ECMAScript5,即ES5,是ECMAScript的第五次修订,于2009年完成标准化,现在的浏览器已经相当于完全实现了这个标准.ECMAScript6,即ES6 ...

  6. loj#6235. 区间素数个数(min25筛)

    题意 题目链接 Sol min25筛的板子题,直接筛出\(g(N, \infty)\)即可 筛的时候有很多trick,比如只存\(\frac{N}{x}\)的值,第二维可以滚动数组滚动掉 #inclu ...

  7. js移动终端浏览器版本

    //当要在不同移动终端浏览器中运行不同的代码时,需要对各个终端浏览器进行判断 //判断浏览器 var browser = { versions: function () { var u = navig ...

  8. Burp Suite插件推荐

    BurpSuiteHTTPSmuggler 网址 https://github.com/nccgroup/BurpSuiteHTTPSmuggler 作用 利用 中间件对 HTTP 协议的实现的特性 ...

  9. Android控件显示和隐藏

    Android控件都有visibility属性,该属性有三个可能值:visible.invisible.gone.可以通过预设或是Java程序控制这些控件的显示或隐藏. 一.在XML配置文件设置 可见 ...

  10. machine learning model(algorithm model) .vs. statistical model

    https://www.analyticsvidhya.com/blog/2015/07/difference-machine-learning-statistical-modeling/ http: ...