FZU Problem 2105 Digits Count
Problem 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
Sample Input
Sample Output
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 <stdio.h>
#include <string.h>
const int N = ; int c, res, a[N*][], flag[N*][], len[N*]; void pushDown( int rt )
{
int ls = * rt; int rs = ls | ;
for( int i = ; i < ; ++i )
{
if( flag[rt][i] == - ) continue;
if( flag[rt][i] == || flag[rt][i] == )
{
a[ls][i] = ( flag[ls][i] = flag[rt][i] ) * len[ls];
a[rs][i] = ( flag[rs][i] = flag[rt][i] ) * len[rs];
flag[rt][i] = -;
}
else if( flag[rt][i] == )
{
flag[rt][i] = -;
}
else
{
a[ls][i] = len[ls] - a[ls][i];
if( flag[ls][i] == - ) flag[ls][i] = ;
else flag[ls][i] ^= ;
a[rs][i] = len[rs] - a[rs][i];
if( flag[rs][i] == - ) flag[rs][i] = ;
else flag[rs][i] ^= ;
flag[rt][i] = -;
} }
} void pushUp( int rt )
{
int ls = * rt; int rs = ls | ;
for( int i = ; i < ; ++i )
a[rt][i] = a[ls][i] + a[rs][i];
} void build( int l, int r, int rt )
{
len[rt] = r - l + ;
if( l == r )
{
scanf("%d", &c);
for( int i = ; i < ; ++i )
a[rt][i] = ( & (c>>i) );
}
else
{
int mid = ( l + r ) / ;
build(l, mid, * rt);
build(mid + , r, * rt + );
pushUp( rt );
}
} void OR( int rt, int opn )
{
for( int i = ; i < ; ++i )
{
if( !( (opn>>i) & ) ) continue;
flag[rt][i] = ;
a[rt][i] = len[rt];
}
} void ADD( int rt, int opn )
{
for( int i = ; i < ; ++i )
{
if( (opn>>i) & ) continue;
flag[rt][i] = ;
a[rt][i] = ;
}
} void XOR( int rt, int opn )
{
for( int i = ; i < ; ++i )
{
if( !( (opn>>i) & ) ) continue;
if( flag[rt][i] == - ) flag[rt][i] = ;
else flag[rt][i] ^= ;
a[rt][i] = len[rt] - a[rt][i];
}
} void query( int l, int r, int rt, const int aa, const int bb )
{
if( aa <= l && r <= bb )
{
res = res + a[rt][] + a[rt][] * + a[rt][] * + a[rt][] * ;
return;
}
pushDown( rt );
int mid = ( l + r ) / ;
int ls = * rt; int rs = ls | ;
if( mid >= aa ) query( l, mid, ls, aa, bb );
if( mid < bb ) query( mid + , r, rs, aa, bb );
} void update( int l, int r, int rt, const int aa, const int bb, const int opn, const int f )
{
if( aa <= l && r <= bb )
{
switch( f )
{
case : OR( rt, opn ); break;
case : ADD( rt, opn ); break;
case : XOR( rt, opn ); break;
}
return;
}
pushDown( rt );
int mid = ( l + r ) / ;
int ls = * rt; int rs = ls | ;
if( mid >= aa ) update( l, mid, ls, aa, bb, opn, f );
if( mid < bb ) update( mid + , r, rs, aa, bb, opn, f );
pushUp( rt );
} int main()
{
int t, n, m, aa, bb, opn; char cmd[];
scanf("%d", &t);
while( t-- )
{
memset( flag, -, sizeof(flag) );
scanf("%d%d", &n, &m);
build(, n-, );
while( m-- )
{
scanf("%s", cmd);
if( cmd[] == 'S' )
{
scanf("%d%d", &aa, &bb);
res = ;
query( , n - , , aa, bb );
printf("%d\n", res);
}
else
{
scanf("%d%d%d", &opn, &aa, &bb);
switch( cmd[] )
{
case 'O': update(, n-, , aa, bb, opn, ); break;
case 'A': update(, n-, , aa, bb, opn, ); break;
case 'X': update(, n-, , aa, bb, opn, ); break;
default : break;
}
}
}
}
return ;
}
FZU Problem 2105 Digits Count的更多相关文章
- FZU 2105 Digits Count(线段树)
Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...
- FZU 2105 Digits Count
Problem 2105 Digits Count Accept: 444 Submit: 2139 Time Limit: 10000 mSec Memory Limit : 2621 ...
- ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】
FZU 2105 Digits Count Time Limit:10000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- FZU 2105 Digits Count(位数计算)
Description 题目描述 Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operation ...
- 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 ...
- FZU 2105 Digits Count(按位维护线段树)
[题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and ...
- FOJ 2105 Digits Count
题意:对一串数字进行抑或某数,和某数,或某数,统计某区间和的操作. 思路:因为化成二进制就4位可以建4颗线段树,每颗代表一位二进制. and 如果该为是1 直接无视,是0则成段赋值为0: or 如 ...
- FZu Problem 2233 ~APTX4869 (并查集 + sort)
题目链接: FZu Problem 2233 ~APTX4869 题目描述: 给一个n*n的矩阵,(i, j)表示第 i 种材料 和 第 j 种材料的影响值,这个矩阵代表这n个物品之间的影响值.当把这 ...
- FZu Problem 2236 第十四个目标 (线段树 + dp)
题目链接: FZu Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里 ...
随机推荐
- sublime 格式化XML文件
下载插件 下载下来后将其解压到D:\tools\Sublime Text 3109\Data\Packages 打开sublime,preferences->browse packages,会弹 ...
- sqlserver ssms ctrl+e快捷键问题
大部分的环境 win2008R2+sqlserver2014R2 ssms 中 ctrl+e都是可以执行查询的,某些情况下,ctrl+e是个组合键 ctrl+e已按下,正在等待按下第二个键 调整方法 ...
- global语句(python学习手册422页)
# -*- coding: cp936 -*- #python 27 #xiaodeng #global语句(python学习手册422页) #实际上就是一个名为__builtin__的模块,但是必须 ...
- 创建简单的Telnet实例
step1.先加入库SuperSocket.Common.dll, SuperSocket.SocketBase.dll, SuperSocket.SocketEngine.dll,log4net.d ...
- history设置时间戳
Linux查看历史命令,很关键!history,默认没有时间戳... 01.设置系统环境变量 echo 'export HISTTIMEFORMAT="%F %T `whoami` &qu ...
- 微信小程序:input输入框和form表单几种传值和取值方式
1.传值:index下标传值.页面navigator传值 1.index下标 实现方式是:data-index="{{index}}"挖坑及e.currentTarget.data ...
- 【mysql】Innodb三大特性之double write
1.doublewrite buffer(mysql官方的介绍) InnoDB uses a novel file flush technique called doublewrite. Before ...
- PHP读取大文件的几种方法
场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件 1.使用file直接读取 <?php $starttime=microtime_float(); ...
- MySQL-关于并发下的mysql_insert_id()
我们在写数据库程序的时候, 经常会需要获取某个表中的最大序号数, 或者刚插入的数据的ID值, 一般情况下获取刚插入的数据的id, 使用select max(id) from table 是可以的, 但 ...
- eclipse 垃圾回收器,内存释放
http://zhangrong-0825-163-com.iteye.com/blog/7334071.如何在eclipse里修改web工程的访问路径,步骤如下: 点击web工程——>选择pr ...