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\)相当于 ...
随机推荐
- [转载] google mock cookbook
原文: https://code.google.com/p/googlemock/wiki/CookBook Creating Mock Classes Mocking Private or Prot ...
- Codeforces 713C Sonya and Problem Wihtout a Legend
题意:给一个序列,可以进行若干次操作,每次操作选择一个数让它+1或-1,问最少要几次操作使得序列变为严格单调递增序列. 题解:首先考虑非严格递增序列,则每个数字最终变成的数字一定是该数组中的某个数.那 ...
- 学习日记day 10 : JavaScript秋风扫落叶第一期
1:实参形参概念清晰化 注意调用,声明和定义的区别. 调用发过去的都是实参,声明和定义中使用的都是形参. 例子: funcOperate (int a); //这是函数声明:参数都是形参: int ...
- (转)Java + Excel 接口自动化
最近项目比较悠闲,想找点事干,写了个 Excel 接口测试的 "框架" 以前用 python 写过一个,这次用 java, 应该说框架都不算,反正就是写了,能帮我解决问题就行. 当 ...
- 省市县distpicker的使用
下载地址https://github.com/fengyuanchen/distpicker 1.引入 <!-- 引入地址 begin --> <script type=" ...
- 5.7 C和C++的关系
- 【HTML5 】<script>元素async,defer异步加载
原文地址:HTML5′s async Script Attribute原文日期: 2010年09月22日翻译日期: 2013年08月22日 (译者注: 异步加载,可以理解为无阻塞并发处理.) (译者再 ...
- 华为 1.static有什么用途?(请至少说明两种)
1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问 ...
- android textview段落开头空格问题
textview中段落开头一般都会空2格排版显示,如果靠编辑空格来解决那就大错特错了,完美的解决方法就是用转义字符"\t",在段首加\t\t就解决啦!
- Hbase之删除数据
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...