FOJ 2105 Digits Count
题意:对一串数字进行抑或某数,和某数,或某数,统计某区间和的操作。
思路:因为化成二进制就4位可以建4颗线段树,每颗代表一位二进制。
and 如果该为是1 直接无视,是0则成段赋值为0;
or 如果是0 无视,是1则成段赋值为1;
xor 成段亦或,1个数和0个数交换;
sum 求和;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include <iostream>
#define N 1000050
#define debug(x) printf(#x"= %d\n",x);
using namespace std;
int sum[][N * ], flag[][N * ], Xor[][N * ];
int a[N];
void pushup(int i, int now) {
sum[now][i] = sum[now][i << ] + sum[now][i << | ];
}
void pushdown(int i, int now, int l, int r) { int mid = (l + r) >> ;
if (flag[now][i] != -) {
flag[now][i << ] = flag[now][i << | ] = flag[now][i];
sum[now][i << ] = (mid - l + ) * flag[now][i];
sum[now][i << | ] = (r - mid) * flag[now][i];
Xor[now][i << ] = Xor[now][i << | ] = ;
flag[now][i] = -;
}
if (Xor[now][i]) {
Xor[now][i << ] ^= ;
sum[now][i << ] = (mid - l + ) - sum[now][i << ];
Xor[now][i << | ] ^= ;
sum[now][i << | ] = (r - mid) - sum[now][i << | ];
Xor[now][i] = ;
}
}
void build(int l, int r, int i, int now) { flag[now][i] = -;
Xor[now][i] = ;
if (l == r) {
sum[now][i] = ((a[l] >> now) & );
return;
}
int mid = (l + r) >> ;
build(l, mid, i << , now);
build(mid + , r, i << | , now);
pushup(i, now);
}
void update(int l, int r, int pl, int pr, int type, int va, int i, int now) {
if (l >= pl && r <= pr) {
if (type == ) {
sum[now][i] = (r - l + ) * va;
flag[now][i] = va;
Xor[now][i] = ;
} else {
sum[now][i] = (r - l + - sum[now][i]);
Xor[now][i] ^= ;
}
return;
}
pushdown(i, now, l, r);
int mid = (l + r) >> ;
if (pl <= mid)
update(l, mid, pl, pr, type, va, i << , now);
if (pr > mid)
update(mid + , r, pl, pr, type, va, i << | , now);
pushup(i, now);
} int query(int l, int r, int pl, int pr, int i, int now) {
if (l >= pl && r <= pr) {
return sum[now][i];
}
pushdown(i, now, l, r);
int mid = (l + r) >> ;
int tmp = ;
if (pl <= mid)
tmp += query(l, mid, pl, pr, i << , now);
if (pr > mid)
tmp += query(mid + , r, pl, pr, i << | , now);
pushup(i, now);
return tmp;
}
int main() {
int n, m, tt;
scanf("%d", &tt);
while (tt--) {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]);
for (int i = ; i < ; ++i)
build(, n, , i);
while (m--) {
char s[];
scanf(" %s", s);
if (strcmp(s, "OR") == ) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
y++;
z++;
for (int i = ; i < ; ++i) {
if ((x >> i) & ) {
update(, n, y, z, , , , i);
}
}
} else if (strcmp(s, "AND") == ) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
y++;
z++;
for (int i = ; i < ; ++i) {
if (((x >> i) & ) == ) {
update(, n, y, z, , , , i);
}
}
} else if (strcmp(s, "XOR") == ) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
y++;
z++;
for (int i = ; i < ; ++i) {
if (((x >> i) & )) {
update(, n, y, z, , , , i);
}
}
} else {
int x, y;
scanf("%d%d", &x, &y);
x++;
y++;
int ans=;
for (int i = ; i < ; ++i) {
ans+=query(,n,x,y,,i)*(<<i);
// debug(ans);
}
printf("%d\n",ans);
}
}
}
return ;
}
FOJ 2105 Digits Count的更多相关文章
- ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】
FZU 2105 Digits Count Time Limit:10000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- 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 ...
- 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 ...
- FZU Problem 2105 Digits Count
Problem Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operati ...
- FZU-2105 Digits Count (两种标记成段更新)
题目大意:给n个0~15之间的数,有3种更新操作,1种询问操作.3种更新操作是:1.让某个闭区间的所有数字与一个0~15之间的数字进行逻辑与运算:2.让某个闭区间的所有数字与一个0~15之间的数字进行 ...
- FZU2105 Digits Count(按位建线段树)题解
题意: 给出区间与.或.异或\(x\)操作,还有询问区间和. 思路: 因为数比较小,我们给每一位建线段树,这样每次只要更新对应位的答案. 与\(0\)和或\(1\)相当于重置区间,异或\(1\)相当于 ...
随机推荐
- caffe的db_lmdb.hpp文件
先总的说一下: 类:LMDBCursor: 它干了点什么?它需要传入参数为:mdb_txn(传入它是因为用完它,把它absort掉), mdb_cursor;它应该是用来读出数据的: 类:LMDBT ...
- xutils使用过程
1,导入xutils的jar包 2,添加xutils需要使用的权限 <uses-permission android:name="android.permission.INTERNET ...
- 【Linux系统】防暴力破解
在日志文件/var/log/secure 中可以看到涉及到安全方面的日志,可以查看是否有人尝试暴力破解及是否成功,对于肉鸡行为有一定帮助 思路基本上都是加强密码的复杂度,增加iptables配置黑名单 ...
- Bootstrap的标题
一.定义标题 Bootstrap和普通的HTML页面一样,定义标题都是使用标签<h1>到<h6>,只不过Bootstrap覆盖了其默认的样式,使用其在所有浏览器下显示的效果一样 ...
- String.join()方法的使用
String.join()方法是JDK1.8之后新增的一个静态方法,使用方式如下所示: String result = String.join("-","java&qu ...
- @requestBody注解的使用
1.@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是ap ...
- 使用 Velocity 模板引擎快速生成代码(zhuan)
http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/ ****************************************** ...
- mismatch位置(MD tag)- sam/bam格式解读进阶
这算是第二讲了,前面一讲是:Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶 MD是mismatch位置的字符串的表示形式,貌似在call SNP和indel的时候会用 ...
- VC++编译zlib
目录 第1章简介 1 第2章版本1.2.3 2 2.1 编译汇编代码 2 2.1.1 32位汇编 2 2.1.2 64位汇编 5 2.2 Visual C++ 6.0 ...
- Laravel 实现定时任务
运行命令schedule run 时laravel会去App\console\kernel.php文件中查找schedule方法,有没有要执行的定时命令 实现流程:首先可以自定义命令并注册命令(参考上 ...