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\)相当于 ...
随机推荐
- SQL SERVER 2008函数大全(含例子)
--SQL SERVER 2008 函数大全 /* author:TracyLee csdncount:Travylee */ /* 一.字符串函数: 1.ascii(字符串表达式) 返回字符串 ...
- (一)mtg3000常见操作
一.查看MTG3000主控板IP地址: 重启设备后一直跑到shell,用户名和密码都输入admin,然后输入en进入命令行界面,输入sh int可查看设备IP等信息. 2.升级app.web程序
- sp工具类编写
package com.itheima.mobilesafe74.utils; import android.content.Context; import android.content.Share ...
- Java异常与运行时异常,以及与线程的关系
具体可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6171103.html 都写在里面了,为了避免更新不一致,这里就不再写一遍了.只给个链接. 注意Java和 ...
- POJ 2385 Apple Catching
比起之前一直在刷的背包题,这道题可以算是最纯粹的dp了,写下简单题解. 题意是说cows在1树和2树下来回移动取苹果,有移动次数限制,问最后能拿到的最多苹果数,含有最优子结构性质,大致的状态转移也不难 ...
- iOS 开发之照片框架详解(2)
一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...
- Android自动检测版本及自动升级
步骤: 1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName. 2.从服务器获取版本号(版本号存在于xml文件中) ...
- ubuntu sudo apt-get update 失败 解决方法
sudo apt-get update 报了一堆错误: Err http://cn.archive.ubuntu.com trusty InRelease Err http://cn.archive. ...
- 各种element/format 在manage display 下的选项
long text = > plain text, summary and trimmed, trimmed,default, hiddenentity refernece => enti ...
- VB6 GDI+ 入门教程[6] 图片
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[6] 图片 2009 年 6 月 19 日 15条评论 ...