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. CENTOS 6.5 配置YUM安装NGINX

    第一步,在/etc/yum.repos.d/目录下创建一个源配置文件nginx.repo: cd /etc/yum.repos.d/ vim nginx.repo 填写如下内容: [nginx]nam ...

  2. xcode8.0升级之后公司项目遇到的问题

    xcode8升级之后项目遇到了问题,由于这个项目是我中途接手的,遇到的第三方也是自己没有用过的, AQGridViewCell,这个第三方的类主要是用于处理图片的问题,xcode开发工具升级过后,报这 ...

  3. 「视频直播技术详解」系列之七:直播云 SDK 性能测试模型

    ​关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 本系列文章大纲如下: ...

  4. 关于在安装MySQL时报错"本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止"的解决方法

    首先将你下载的MySQL安装或者解压(对应安装版和解压版),下载地址http://dev.mysql.com/downloads/mysql/ 然后复制你安装目录中的my-default.ini,更改 ...

  5. (七)Transformation和action详解-Java&Python版Spark

    Transformation和action详解 视频教程: 1.优酷 2.YouTube 什么是算子 算子是RDD中定义的函数,可以对RDD中的数据进行转换和操作. 算子分类: 具体: 1.Value ...

  6. nodejs安装和环境部署

    windows 下: 1. 下载windows平台nodejs环境安装包,百度一下nodejs官网,找到DOWNLOADS点击,找到Windows Installer 如果为64位电脑可以选择64位版 ...

  7. mount常用挂载命令

    挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o optio ...

  8. Sql Server 2016新功能之 Row-Level Security

    Sql Server 2016 有一个新功能叫 Row-Level Security ,大概意思是行版本的安全策略(原来我是个英语渣_(:з」∠)_) 直接上例子.这个功能相当通过对表添加一个函数作为 ...

  9. monkeyrunner之坐标或控件ID获取方法-续

    在之前的文章中,介绍过控件坐标和ID的获取方法,这里,我们再介绍一个新的工具-uiautomatorviewer. Uiautomatorviewer是Android sdk自带的工具,位置在sdk/ ...

  10. [游戏开发-学习笔记]菜鸟慢慢飞(九)- NGUI- UIWidget(官方说明翻译)