传送门

•题意

  给你一个包含 n 个数的序列 a,定义序列上的两个操作:

    (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$;

    (2)$2,l,r,x\ :\ \forall\ i \in[l,r],a_i = a_i\ xor\ x$;

  输出操作(1)对应的 ans 值;

•题解

  因为是异或操作,而异或设计的运算都是在二进制上进行的;

  所以考虑按照二进制位建立线段树;

  对于每个叶节点,将对应的数转化成二进制的每一位存入到节点信息中;

  然后就是区间更新,区间查询操作;

•Code

  CodeForces242E(1).cpp

•CF242E升级版

  题目来源与 【2019ICPC亚洲区域赛银川赛站网络预选赛A. Simple Data Structures

  相比于 CF242E 这道题,对序列的操作增加了两个:

    (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$;

    (2)$2,l,r,x\ :\ \forall\ i \in[l,r],a_i = a_i\ xor\ x$;

    (3)$2,l,r,x\ :\ \forall\ i \in[l,r],a_i = a_i\ |\  x$

    (4)$2,l,r,x\ :\ \forall\ i \in[l,r],a_i = a_i\ \&\  x$

•思路

  和上题思路差不多,考虑到开 20 棵线段树维护以上操作;

  难点在于如何 lazy,以及如何 pushDown();

  考虑到 ^,|,& 的特点;

  对于某个数的二进制的第 i 位,假设为 bit[i];

  易得 bit[i] ^ 0 = bit[i] , bit[i] | 0 = bit[i] , bit[i] &1 = bit[i];

     bit[i] ^ 1 : 相当于反转 bit[i];

     bit[i] | 1 = 1;

     bit[i] & 0 = 0;

  也就是说只有后三个操作才有用;

  考虑到 bit[i] 可能在这之前不止做依次操作;

  但是有一点可以肯定,遇到 bit[i] | 1,bit[i] = 1,不管其之前做过何种操作;

  同样,遇到 bit[i]&0,bit[i]=0;

  而如果先遇到 &0 , 在遇到 ^ 1,相当于将 bit[i] 赋值为 1;

  反之,如果先遇到 |1 , 在遇到 ^ 1,相当于将 bit[i] 赋值为 0;

  这样的话,定义 lazy 有四个取值:

    $lazy=\begin{cases} -1\ ,\ no\ operate\\ \ 0\ \ ,\ become\ 0 \\ \ 1\ \ ,\ become\ 1 \\ \ 2\ \ ,\ reverse\end{cases}$;

  向下传递懒惰标记的时候,要结合父节点的 lazy 和子节点的 lazy 进行更新;

•Code

  CodeForces242E(2).cpp

CodeForces 242E "XOR on Segment"(线段树)的更多相关文章

  1. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

  2. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  3. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  4. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  5. Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

    题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...

  6. XOR on segment(线段树区间异或更新)

    原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...

  7. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  8. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  9. CodeForces 516C Drazil and Park 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...

随机推荐

  1. 2018-11-30-WPF-解决-ListView-的滚动条不显示

    title author date CreateTime categories WPF 解决 ListView 的滚动条不显示 lindexi 2018-11-30 19:24:57 +0800 20 ...

  2. java.lang.StackOverflowError 解决办法

    java.lang.StackOverflowError com.sxt.servlet.servlet1.LoginServlet.doGet(LoginServlet.java:15) com.s ...

  3. Java练习 SDUT - 2669_2-2 Time类的定义

    2-2 Time类的定义 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 通过本题目的练习可以掌握类与对象的定义: 设计 ...

  4. docker保存容器的修改

    docker保存容器修改 通过在容器中运行某一个命令,可以把对容器的修改保存下来, 这样下次可以从保存后的最新状态运行该容器.docker中保存状态的过程称之为committing, 它保存的新旧状态 ...

  5. 命令行的形式运行php

    转自:http://www.cnblogs.com/myjavawork/articles/1869205.html 注意:在安装php时需要将php 的安装目录加到环境变量 PATH 中 (右击我的 ...

  6. jQuery show hide方法 二级菜单

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Python中的socket

    socket()模块函数用法 import socket socket.socket(socket_family,socket_type,protocal=0) socket_family 可以是 A ...

  8. Docker 学习笔记 2019-05-27

    Docker 学习笔记 2019-05-27 可以很方便的打包应用. 使用 docker-compose 更方便. 每个发行版安装方式不一样,如果 centos 直接安装很可能会安装成旧版本. Lin ...

  9. python 嵌套列表

  10. Redis源码解析:05跳跃表

    一:基本概念 跳跃表是一种随机化的数据结构,在查找.插入和删除这些字典操作上,其效率可比拟于平衡二叉树(如红黑树),大多数操作只需要O(log n)平均时间,但它的代码以及原理更简单.跳跃表的定义如下 ...