FZU 2105Digits Count(线段树 + 成段更新)
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 <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int Max = + ;
int n, m;
struct Node
{
int l, r;
int num;
};
Node node[Max * ];
int A[Max];
void buildtree(int l, int r, int k)
{
node[k].l = l;
node[k].r = r;
node[k].num = -;
if (l == r)
{
node[k].num = A[l];
return;
}
int mid = (l + r) / ;
buildtree(l, mid, k * );
buildtree(mid + , r, k * + );
if (node[k * ].num >= && node[k * ].num == node[k * + ].num) // 如果左边区间和右边区间 num 相同,就要更改父节点
{
node[k].num = node[k * ].num;
}
}
int getopt(int num, int opn, int opt)
{
if (opt == )
return opn & num;
if (opt == )
return opn | num;
if (opt == )
return (opn ^ num);
return ;
}
void update(int l, int r, int k, int opn, int opt)
{
if (node[k].l == l && node[k].r == r && node[k].num >= )
{
// 区间【l, r】上的数是相同的,只需改一次就ok了
node[k].num = getopt(node[k].num, opn, opt);
return;
}
// 不相同的话就继续往左右两边改
if (node[k].num >= ) // 在改的过程中发现该点标记过,分给子节点,去掉自己的标记
{
node[k * ].num = node[k * + ].num = node[k].num;
node[k].num = -;
}
int mid = (node[k].l + node[k].r) / ;
if (r <= mid)
update(l, r, k * , opn, opt);
else if (mid < l)
{
update(l, r, k * + , opn, opt);
}
else
{
update(l, mid, k * , opn, opt);
update(mid + , r, k * + , opn, opt);
}
if (node[k * ].num >= && node[k * ].num == node[k * + ].num)
node[k].num = node[k * ].num;
}
LL querry(int l, int r, int k)
{
if (node[k].l == l && node[k].r == r && node[k].num >= )
{
return (LL) node[k].num * (LL) (node[k].r - node[k].l + );
}
if (node[k].num >= )
{
node[k * ].num = node[k * + ].num = node[k].num;
node[k].num = -;
}
int mid = (node[k].r + node[k].l) / ;
if (r <= mid)
{
return querry(l, r, k * );
}
else if (mid < l)
{
return querry(l, r, k * + );
}
else
return querry(l, mid, k * ) + querry(mid + , r, k * + );
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%d", &A[i]);
buildtree(, n, );
while (m--)
{
char opt[];
int opn, a, b;
scanf("%s", opt);
if (opt[] == 'S')
{
scanf("%d%d", &a, &b);
printf("%I64d\n", querry(a + , b + , ));
}
else
{
scanf("%d%d%d", &opn, &a, &b);
if (opt[] == 'A')
{
update(a + , b + , , opn, );
}
else if (opt[] == 'O')
{
update(a + , b + , , opn, );
}
else
update(a + , b + , , opn, );
}
}
}
return ;
}
FZU 2105Digits Count(线段树 + 成段更新)的更多相关文章
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
- ZOJ 1610 Count the Colors (线段树成段更新)
题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个 分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以 ...
- ACM: Copying Data 线段树-成段更新-解题报告
Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...
- Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
- hdu 4747【线段树-成段更新】.cpp
题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...
- HDU1698_Just a Hook(线段树/成段更新)
解题报告 题意: 原本区间1到n都是1,区间成段改变成一个值,求最后区间1到n的和. 思路: 线段树成段更新,区间去和. #include <iostream> #include < ...
- HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )
线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
随机推荐
- Atitit mac os 版本 新特性 attilax大总结
Atitit mac os 版本 新特性 attilax大总结 1. Macos概述1 2. 早期2 2.1. Macintosh OS (系统 1.0) 1984年2 2.2. Mac OS 7. ...
- 使用AxisHelper帮助理解View and Data API中的坐标系统
大家使用View and Data API做三维模型开发,必然首先要理解View and Data API的坐标系统,即XYZ三个轴向分别是怎么定义的.Three.js里面提供了一个AxisHelpe ...
- BCS datetime 时间区间问题
BCS 整合sql表时发现以下问题: datetime字段在列表中带了时区,比如插入12-6号的数据,在sql中显示的是12-5 date类型字段无法正确识别,插入成功但报错 LobSystem (外 ...
- iOS网络3—UIWebView与WKWebView使用详解
一.整体介绍 UIWebView自iOS2就有,WKWebView从iOS8才有,毫无疑问WKWebView将逐步取代笨重的UIWebView.通过简单的测试即可发现UIWebView占用过多内存,且 ...
- 12、产品经理要阅读的书籍 - IT软件人员书籍系列文章
产品经理是软件产品的主要领导者.不同于项目经理,产品经理是对产品负责,更多的是负责产品的设计定型:而项目经理则对项目负责,更多的是负责项目软件的实现.产品经理的一些工作,和项目经理是一致的,比如需求分 ...
- 如何在 Evernote 中支持代码高亮
Evernote 本身不支持代码高亮,在 Apple App-Store 上有一个建立在 Evernote 上的 EverCode,可以支持代码高亮,需要付费.虽然只有¥5,但是这个 App 似乎只能 ...
- Scala 数据类型(二)
Scala 与 Java有着相同的数据类型,下表列出了 Scala 支持的数据类型: Byte8位有符号补码整数.数值区间为 -128 到 127 Short16位有符号补码整数.数值区间为 -327 ...
- CSS3:text-overflow实现文字截取,超出部分显示省略号
1. 概述 使用text-overflow:ellipsis对溢出文本显示省略号有两个好处, 一是不用通过后端程序截取: 二是有利于SEO. 2. text-overflow的属性 clip: 当对象 ...
- 关于SQL Server镜像的一个小误区
昨天晚上突然接到客户的电话, 说在配置了镜像的生产环境数据库下修改 “已提交读快照” 选项的时候报错, 需要先取消镜像然后再重新搭建.悲催的是这是个近TB的数据库,问我有没有什么快速的方法.于是我就问 ...
- hadoop程序问题:java.lang.IllegalArgumentException: Wrong FS: hdfs:/ expected file:///
Java代码如下: FileSystem fs = FileSystem.get(conf); in = fs.open(new Path("hdfs://192.168.130.54:19 ...