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?

给定N个整数A={A[0],A[1],...,A[N-1]}。下面有一些操作。

操作1:AND opn L R

其中opn,L和R都是整数。

对于L≤i≤R,我们使A[i]=A[i] AND opn(这里的"AND"是位运算)。

操作2:OR opn L R

其中opn,L和R都是整数。

对于L≤i≤R,我们使A[i]=A[i] OR opn(这里的"OR"是位运算)。

操作3:XOR opn L R

其中opn,L和R都是整数。

对于L≤i≤R,我们使A[i]=A[i] XOR opn(这里的"XOR"是位运算)。

操作4:SUM L R

我们想要知道A[L]+A[L+1]+...+A[R]的值。

现在,你能解决这个简单的问题吗?

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)

第一行有一个整数T,表示测试样例的数量。(T≤100)

后面有T个样例,每个样例的第一行有2个整数n和m(1≤n≤1,000,000, 1≤m≤100,000),表示元素数量与操作次数。

下一行有n个整数A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n)。

接着m行,每行都是上述4种操作的其中一个。(0≤opn≤15)

Output

输出

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

对于每个测试样例的每个"SUM"操作,都要输出到单独的一行。

Sample Input - 输入样例

Sample Output - 输出样例

1

4 4

1 2 4 7

SUM 0 2

XOR 5 0 0

OR 6 0 3

SUM 0 2

7

18

【题解】

  单纯的线段树。

  利用线段树查找快速的特点保存元素,对于某段区间内相同状态的元素进行合并。

  进行操作的时候不断查找,直到可操作的区间。因为数据都是非负整数,所以可以用负数标记元素不同的区间。

  PS:状态发生变化的时候都要下压,注意深入的方向。

  PS2:简单的运算速度是高于开辟空间的速度,所以没必要把线段树每个节点的左右区间都记录下来。

  PSP:开辟元素数量4倍的空间一定够用。

【代码 C++】

 #include<cstdio>
int data[ << ], opn, L, R;
char ts[];
int build(int data_i, int L, int R){//[L, R]
if (L == R) scanf("%d", &data[data_i]);
else{
int mid = (L + R) >> ;// [L, mid] (mid, R]
L = build(data_i << | , L, mid);
R = build(data_i + << , mid + , R);
if (L == R) data[data_i] = L;
else data[data_i] = -;
}
return data[data_i];
}
int bitwise_peration(int data_i, int L_now, int R_now){
if (data[data_i] != - && L <= L_now && R_now <= R){
if (*ts == 'A') data[data_i] &= opn;
else if (*ts == 'O') data[data_i] |= opn;
else if (*ts == 'X') data[data_i] ^= opn;
}
else{
if (data[data_i] != -) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid){// goto Right
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = data[data_i + << ];
}
else if (mid < L){// goto Left
L_now = data[data_i << | ];
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
else{
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
if (L_now == R_now) data[data_i] = L_now;
else data[data_i] = -;
}
return data[data_i];
}
int sum(int data_i, int L_now, int R_now){
if (data[data_i] != - && L <= L_now && R_now <= R){
return data[data_i] * (R_now - L_now + );
}
if (data[data_i] != -) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid) return sum(data_i << | , L_now, mid);
if (mid < L) return sum(data_i + << , mid + , R_now);
return sum(data_i << | , L_now, mid) + sum(data_i + << , mid + , R_now);
}
int main(){
int t, m, n, i;
for (scanf("%d", &t); t; --t){
scanf("%d%d", &n, &m);
--n;
build(, , n);
while (m--){
scanf("%s", ts);
if (*ts == 'S'){
scanf("%d%d", &L, &R);
printf("%d\n", sum(, , n));
}
else{
scanf("%d%d%d", &opn, &L, &R);
bitwise_peration(, , n);
}
}
}
return ;
}
 #include<cstdio>
int L, R;
char data[], opn, ts[];
int read_g(){// 输入挂
int add = getchar() - '';
int a = getchar();
while (a >= '' && a <= '') add = add * + a - '', a = getchar();
return add;
}
int build(int data_i, int L, int R){// [L, R]
if (L == R) data[data_i] = read_g();
else{// [L, mid] (mid, R]
int mid = (L + R) >> ;
L = build(data_i << | , L, mid);
R = build(data_i + << , ++mid, R);
if (L == R) data[data_i] = L;
else data[data_i] = -;
}
return data[data_i];
}
int bitwise_peration(int data_i, int L_now, int R_now){
if (~data[data_i] && L <= L_now && R_now <= R){
if (*ts == 'A') data[data_i] &= opn;
else if (*ts == 'O') data[data_i] |= opn;
else if (*ts == 'X') data[data_i] ^= opn;
}
else{
if (~data[data_i]) data[data_i << | ] = data[data_i + << ] = data[data_i];
int mid = (R_now + L_now) >> ;
if (R <= mid){// goto Right
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = data[data_i + << ];
}
else if (mid < L){// goto Left
L_now = data[data_i << | ];
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
else{
L_now = bitwise_peration(data_i << | , L_now, mid);
R_now = bitwise_peration(data_i + << , mid + , R_now);
}
if (L_now == R_now) data[data_i] = L_now;
else data[data_i] = -;
}
return data[data_i];
}
int sum(int data_i, int L_now, int R_now){
if (~data[data_i]){
if (L_now < L) L_now = L;
if (R < R_now) R_now = R;
return data[data_i] * (++R_now - L_now);
}
int mid = (R_now + L_now) >> ;
if (R <= mid) return sum(data_i << | , L_now, mid);
if (mid < L) return sum(++data_i << , ++mid, R_now);
return sum(data_i << | , L_now, mid) + sum(data_i + << , mid + , R_now);
}
int main(){
int m, n;
short t = read_g();
while (t--){
n = read_g(); m = read_g(); --n;
build(, , n);
while (m--){
scanf("%s", ts); getchar();
if (*ts == 'S'){
L = read_g(); R = read_g();
printf("%d\n", sum(, , n));
}
else{
opn = read_g(); L = read_g(); R = read_g();
bitwise_peration(, , n);
}
}
}
return ;
}

FZU 2105

FZU 2105 Digits Count(位数计算)的更多相关文章

  1. ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】

     FZU 2105  Digits Count Time Limit:10000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  2. FZU 2105 Digits Count(线段树)

    Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...

  3. FZU 2105 Digits Count

     Problem 2105 Digits Count Accept: 444    Submit: 2139 Time Limit: 10000 mSec    Memory Limit : 2621 ...

  4. fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛

    http://acm.fzu.edu.cn/problem.php?pid=2105 Problem Description Given N integers A={A[0],A[1],...,A[N ...

  5. FZU 2105 Digits Count(按位维护线段树)

    [题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and ...

  6. FZU Problem 2105 Digits Count

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

  7. FOJ 2105 Digits Count

    题意:对一串数字进行抑或某数,和某数,或某数,统计某区间和的操作. 思路:因为化成二进制就4位可以建4颗线段树,每颗代表一位二进制. and 如果该为是1  直接无视,是0则成段赋值为0: or  如 ...

  8. FZU 2105 (线段树)

     Problem 2105 Digits Count  Problem Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we h ...

  9. FZU-2105 Digits Count (两种标记成段更新)

    题目大意:给n个0~15之间的数,有3种更新操作,1种询问操作.3种更新操作是:1.让某个闭区间的所有数字与一个0~15之间的数字进行逻辑与运算:2.让某个闭区间的所有数字与一个0~15之间的数字进行 ...

随机推荐

  1. 视频处理控件TVideoGrabber如何对屏幕进行录制/压缩

    TVideoGrabber可以对屏幕进行录制和压缩,本文来详细的说明在多种情况下TVideoGrabber是如何实现屏幕的录制和压缩. 屏幕录制 当VideoSource = vs_ScreenRec ...

  2. 强制类型转换(const_cast)

    [1] const_cast的作用 一.常量指针被转化成非常量指针,并且仍然指向原来的对象: 二.常量引用被转换成非常量引用,并且仍然指向原来的对象: 三.常量对象被转换成非常量对象. [2] 实例代 ...

  3. PHP判断客户端是PC web端还是移动手机端方法

    PHP判断客户端是PC web端还是移动手机端方法需要实现:判断手机版的内容加上!c550x260.jpg后缀变成缩略图PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能 ...

  4. eclipse Juno Indigo Helios Galileo这几种版本的意思

    Eclipse 3.1 版本代号 IO [木卫1,伊奥]   Eclipse 3.2, 30-06-2006, Callisto projects, 版本代号 Callisto [木卫四,卡里斯托 ] ...

  5. Spring+Mybatis整合报错Mapped Statements collection does not contain value原因之一

    报错如下: ### Error updating database. Cause: java.lang.IllegalArgumentException: Mapped Statements coll ...

  6. phpize 动态添加 PHP 扩展的错误及解决方案

    使用phpize 动态添加 PHP 扩展是开发中经常需要做的事情,但是在 macOS 中,首次使用该功能必然会碰到一些错误,本文列出了这些错误的解决方法. 问题一: 执行 phpize 报错如下: $ ...

  7. NSDictionary to jsonString || 对象转json格式

    -(NSString*)DataTOjsonString:(id)object { NSString *jsonString = nil; NSError *error; NSData *jsonDa ...

  8. 20145227《Java程序设计》第3次实验报告

    20145227<Java程序设计>第3次实验报告 实验步骤与内容 一.实验内容 XP基础 XP核心实践 相关工具 二.实验过程 (一)敏捷开发与XP 1.XP是以开发符合客户需要的软件为 ...

  9. 理解css中的position-static\relative\fixed\absolute

    position属性有四个值: static(静态定位):是默认值,不会被特殊的定位,遵循正常的文档流对象,对象占用文档空间,该方式下,top.right.bottom.left.z-index等属性 ...

  10. JAVA基础知识之网络编程——-使用Proxy创建连接

    在前面的HTTP网络通信的例子中,使用了URLConnection conn = url.openConnection();连接网络, 如果改用URLConnection conn = url.ope ...