Description

Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations:

Operation 1: AND opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] AND opn (here "AND" is bitwise operation).

Operation 2: OR opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] OR opn (here "OR" is bitwise operation).

Operation 3: XOR opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] XOR opn (here "XOR" is bitwise operation).

Operation 4: SUM L R

We want to know the result of A[L]+A[L+1]+...+A[R].

Now can you solve this easy problem?

Input

The first line of the input contains an integer T, indicating the number of test cases. (T≤100)

Then T cases, for any case, the first line has two integers n and m (1≤n≤1,000,000, 1≤m≤100,000), indicating the number of elements in A and the number of operations.

Then one line follows n integers A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n).

Then m lines, each line must be one of the 4 operations above. (0≤opn≤15)

Output

For each test case and for each "SUM" operation, please output the result with a single line.

Sample Input

1 4 4 1 2 4 7 SUM 0 2 XOR 5 0 0 OR 6 0 3 SUM 0 2

Sample Output

7 18

Hint

A = [1 2 4 7]

SUM 0 2, result=1+2+4=7;

XOR 5 0 0, A=[4 2 4 7];

OR 6 0 3, A=[6 6 6 7];

SUM 0 2, result=6+6+6=18.

大神说,经过若干次的操作就会出现很多相同的,然后懒惰标记就用来记做 这个区间又没用相同的

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int Max = + ;
int n, m;
struct Node
{
int l, r;
int num;
};
Node node[Max * ];
int A[Max];
void buildtree(int l, int r, int k)
{
node[k].l = l;
node[k].r = r;
node[k].num = -;
if (l == r)
{
node[k].num = A[l];
return;
}
int mid = (l + r) / ;
buildtree(l, mid, k * );
buildtree(mid + , r, k * + );
if (node[k * ].num >= && node[k * ].num == node[k * + ].num) // 如果左边区间和右边区间 num 相同,就要更改父节点
{
node[k].num = node[k * ].num;
}
}
int getopt(int num, int opn, int opt)
{
if (opt == )
return opn & num;
if (opt == )
return opn | num;
if (opt == )
return (opn ^ num);
return ;
}
void update(int l, int r, int k, int opn, int opt)
{
if (node[k].l == l && node[k].r == r && node[k].num >= )
{
// 区间【l, r】上的数是相同的,只需改一次就ok了
node[k].num = getopt(node[k].num, opn, opt);
return;
}
// 不相同的话就继续往左右两边改
if (node[k].num >= ) // 在改的过程中发现该点标记过,分给子节点,去掉自己的标记
{
node[k * ].num = node[k * + ].num = node[k].num;
node[k].num = -;
}
int mid = (node[k].l + node[k].r) / ;
if (r <= mid)
update(l, r, k * , opn, opt);
else if (mid < l)
{
update(l, r, k * + , opn, opt);
}
else
{
update(l, mid, k * , opn, opt);
update(mid + , r, k * + , opn, opt);
}
if (node[k * ].num >= && node[k * ].num == node[k * + ].num)
node[k].num = node[k * ].num;
}
LL querry(int l, int r, int k)
{
if (node[k].l == l && node[k].r == r && node[k].num >= )
{
return (LL) node[k].num * (LL) (node[k].r - node[k].l + );
}
if (node[k].num >= )
{
node[k * ].num = node[k * + ].num = node[k].num;
node[k].num = -;
}
int mid = (node[k].r + node[k].l) / ;
if (r <= mid)
{
return querry(l, r, k * );
}
else if (mid < l)
{
return querry(l, r, k * + );
}
else
return querry(l, mid, k * ) + querry(mid + , r, k * + );
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%d", &A[i]);
buildtree(, n, );
while (m--)
{
char opt[];
int opn, a, b;
scanf("%s", opt);
if (opt[] == 'S')
{
scanf("%d%d", &a, &b);
printf("%I64d\n", querry(a + , b + , ));
}
else
{
scanf("%d%d%d", &opn, &a, &b);
if (opt[] == 'A')
{
update(a + , b + , , opn, );
}
else if (opt[] == 'O')
{
update(a + , b + , , opn, );
}
else
update(a + , b + , , opn, );
}
}
}
return ;
}

FZU 2105Digits Count(线段树 + 成段更新)的更多相关文章

  1. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  2. ZOJ 1610 Count the Colors (线段树成段更新)

    题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个 分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以 ...

  3. ACM: Copying Data 线段树-成段更新-解题报告

    Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...

  4. 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. 这题 ...

  5. hdu 4747【线段树-成段更新】.cpp

    题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...

  6. HDU1698_Just a Hook(线段树/成段更新)

    解题报告 题意: 原本区间1到n都是1,区间成段改变成一个值,求最后区间1到n的和. 思路: 线段树成段更新,区间去和. #include <iostream> #include < ...

  7. HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

    线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...

  8. poj 3468 A Simple Problem with Integers 【线段树-成段更新】

    题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...

  9. POJ3468_A Simple Problem with Integers(线段树/成段更新)

    解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...

随机推荐

  1. Atitit 在线支付系统功能设计原理与解决方案 与目录

    Atitit 在线支付系统功能设计原理与解决方案 与目录 1.1. 支付系统1 1.2. 独立的支付子体系..微服务架构..1 1.3. 参考书籍1 支付战争 [The PayPal Wars:Bat ...

  2. iOS 杂笔-如何解决tableview显示错乱问题

    解决自定义Tableviewcell显示错乱问题 要是要解决这个问题,就需要用到UITableviewCell的prepareForReuse方法 cell被重用如何提前知道? 重写cell的prep ...

  3. although 和 although 的区别

    作为连词的时候,although 和 though 是可以互换的.Although 一般被认为更加正式一些.比如,以下的这些句子: Growth in Europe is maintaining mo ...

  4. Hibernate 系列 01 - 框架技术 (介绍Hibernate框架的发展由来)

    引导目录: Hibernate 系列教程 目录 本篇导航: 为什么学习框架技术 框架的概念 主流框架的介绍 1.为什么学习框架技术 如何制作一份看上去具有专业水准的PPT文档呢?一个简单的方法就是使用 ...

  5. ORACLE推导参数Derived Parameter介绍

    Oracle的推导参数(Derived Parameters)其实是初始化参数的一种.推导参数值通常来自于其它参数的运算,依赖其它参数计算得出.官方文档关于推导参数(Derived Parameter ...

  6. Oracle 哈希连接原理

    <基于Oracle的sql优化>里关于哈希连接的原理介绍如下: 哈希连接(HASH JOIN)是一种两个表在做表连接时主要依靠哈希运算来得到连接结果集的表连接方法. 在Oracle 7.3 ...

  7. jquery的几个常用方法

    第一部份关键词: .bind() .unbind() .css() .hasclass() .removeclass .parent() .children() .html() .hide() .sh ...

  8. 2、实现不同子网之间的信息交流(互相可以PING通)

    一.环境: 二个不同的虚拟子网 VMnet1: 192.168.155.0/24 VMnet8: 192.168.170.0/24 编辑 --> 虚拟网络编辑器 (查看自己的子网,相应修改就行) ...

  9. Ubuntu 14.04 LTS 下升级 gcc 到 gcc-4.9、gcc-5 版本

    如果没记错的话,阿里云ECS上的Ubuntu也是LTS版本. 如果还在使用较旧版本的Ubuntu,或者是Ubuntu LTS,那么我们是很难体验新版gcc的.怎么办呢? 我们或许可以自己去编译用旧版本 ...

  10. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...