CodeChef - ANDMIN —— 线段树 (结点最多被修改的次数)
题目链接:https://vjudge.net/problem/CodeChef-ANDMIN
Read problems statements in Mandarin Chinese, Russian and Vietnamese as well.
You are given an array of N integers. You should support the following queries on this array.
- 0 L R : Find the minimum integer in the range AL, AL+1, ..., AR.
- 1 L R X : You should apply the assignment A[i] = A[i] & X, for all indices i in range [L, R], where & denotes bitwise AND operation.
Input
First line of the input contains two space separated integers N and Q.
Second line contains N integer numbers denoting array A.
In the next Q lines, each contain one of the queries described above.
Output
For each query of the type 0, output a single line containing the answer of the query.
Constraints
- 1 ≤ N, Q ≤ 105
- 1 ≤ Ai, X ≤ 109
- 1 ≤ L ≤ R ≤ N
Example
Input:
5 5
1 5 2 3 4
0 2 5
1 1 5 6
0 2 2
1 2 5 3
0 1 3
Output:
2
4
0
题意:
给出一个序列。有两种操作:0 L R,查询区间 [L, R]的最小值,1 L R X,对区间[L,R]中的每个数与x作与操作。
题解:
1.线段树的应用。可知对于一个int类型的值,最少只需做31次与操作,每一位上的值都全部为0。
2.构架线段树,线段树中的每个结点,除了记录当前段的最小值之外,还需记录一个状态,这个状态即:这一段中,有哪些位是为1的。当此段的这个位为1,且x的这个位为0,那么就可以继续往下更新,把这个段中的这个位置为0;否则,当此段的这个位为0,而x的这个位为0,那么就无需往下更新了,因为做的是无用功。
反思:
1.自己开始时的想法是:如果这一段的数不全为0,那么就往下更新,因为期望着在如若干操作之后,这些区间的值都会变成0,那么时间限制应该不成为题。然而这只是很幼稚的想法,如果x都是1111111111,那岂不是每一次都要往下更新到根节点,但值又不发生任何改变,即做了很多无用功。
2.计算机都讲究效率,我们想只做有用功。所以,就必须清楚哪些是有用功,哪些是无用功。对于此题,如果x不能改变当前段的任何一个值,那么执行它就是无用功了。所以,在线段树的每个节点中,记录有哪些位的值为1,当x的此位也为1,那么次操作就是有用功,否则是无用功。
3.线段树的结点,就是记录当前段,或者说当前集合的公共信息,常见是最大最小值、和,当然还可以是很多天马行空的信息,要大胆想。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int Int_Max = (<<)-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e5+; int minv[MAXN<<], state[MAXN<<];
void push_up(int u)
{
minv[u] = min(minv[u*], minv[u*+]);
state[u] = state[u*]|state[u*+]; //信息集合
} void build(int u, int l, int r)
{
if(l==r)
{
scanf("%d", &minv[u]);
state[u] = minv[u];
return;
} int mid = (l+r)>>;
build(u*, l, mid);
build(u*+, mid+, r);
push_up(u);
} void add(int u, int l, int r, int x, int y, int val)
{
int tmpDel = state[u]&val; //对当前段与删除标签进行求与,得到的即为当前段可置0的位置的集合
if(tmpDel==) return; //如果没有位置可以置为0,则直接退出
if(l==r)
{
minv[u] ^= tmpDel;
state[u] ^= tmpDel;
return;
} int mid = (l+r)>>;
if(x<=mid) add(u*, l, mid, x, y, val);
if(y>=mid+) add(u*+, mid+, r, x, y, val);
push_up(u);
} int query(int u, int l, int r, int x, int y)
{
if(x<=l && r<=y)
return minv[u]; int ret = INF;
int mid = (l+r)>>;
if(x<=mid) ret = min(ret, query(u*, l, mid, x, y));
if(y>=mid+) ret = min(ret, query(u*+, mid+, r, x, y));
push_up(u);
return ret;
} int main()
{
int n, m;
scanf("%d%d", &n,&m);
build(,,n);
int op, L, R, val;
while(m--)
{
scanf("%d", &op);
if(op==)
{
scanf("%d%d", &L, &R);
printf("%d\n", query(,,n,L,R));
}
else
{
scanf("%d%d%d", &L,&R,&val);
add(,,n,L,R,(val^Int_Max)); //对val进行按位取反。
}
}
}
CodeChef - ANDMIN —— 线段树 (结点最多被修改的次数)的更多相关文章
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- HDU1698 线段树入门之区间修改/查询(lazy标记法)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- codevs1081 线段树练习 2<区间修改>
1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有 ...
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模
D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his h ...
- 最大数maxnumber (HYSBZ 1012)(线段树区间查询和单点修改)(优雅的暴力)
Problem 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L 个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作 ...
- 2020牛客寒假算法基础集训营2 J.求函数 (线段树 推公式 单点修改 区间查询)
https://ac.nowcoder.com/acm/contest/3003/J 题解: #include<bits/stdc++.h> typedef long long ll; u ...
- 【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****
[codevs2216]行星序列 2014年2月22日3501 题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小 ...
- kb-07线段树-05-区间整体修改查询;(水)
/* */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; s ...
- 【codevs】1082 线段树练习 3 <区间修改+区间和>
题目连接 http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...
随机推荐
- ExtJs4学习(一):正确认识ExtJs4
认识ExtJs 1.Javat能用ExtJs吗? 它是展现层的技术,与JS,HTML,CSS有关.至于server端是.Net,还是PHP等无关. 2.ExtJs适合什么样的项目? 依照官方的说法,E ...
- Node.js学习笔记(3)——关于回调函数和函数的回调
说明:本人是node.js的初学者,尝试向别人解释这是怎么回事是自我学习的一个好方法.如果你发现有些地方并不是那么正确,欢迎提出来让我知道以便修正,共同进步,谢过^_^. 欢迎交流,本人微 ...
- window.opener
window.opener 实际上就是通过window.open打开的窗体的父窗体. 比如在父窗体parentForm里面 通过 window.open("subForm.html" ...
- Win 8.1 安装后要做的优化
①无光驱恢复电脑或重置系统(无需插入介质,本来老提示插入介质) 1.准备工作:win8iso,解压到任意非系统盘,解压后的路径假如是:H:\OS\win8 2.接着以管理员身份启动命令提示符,输入 ...
- msgsnd的一个小问题
今天写了一个System V消息队列的小样例.定义了一个例如以下的结构体: #define MSG_SIZE 8192 struct request { long mtype; int client_ ...
- Pentaho Work with Big Data(五)—— 格式化原始web日志
本演示样例说明怎样使用Pentaho MapReduce把原始web日志解析成格式化的记录. 一.向HDFS导入演示样例数据文件 将weblogs_rebuild.txt文件放到HDFS的/user/ ...
- dede中可以用系统设置中的添加新变量来调用频繁改变的文字内容
这样真正使所有内容都可以在后台控制.
- Oracle SQL 查询优化.Part4
一.插入 insert 操作: 1. 复制表结构但不新增数据: -- 复制表结构但不插入数据 create table emp_new as select * from emp where 1 = 2 ...
- Android应用的电量消耗和优化的策略
对于Android移动应用的开发者来说,耗电量的控制一直是个老大难问题. 我们想要控制耗电量,必须要有工具或者方法比较准确的定位应用的耗电情况.下面,我们先来分析下如何计算android应 ...
- 深入浅出Attribute(二)
上篇里,我们把Attribute“粘”在类的成员方法上show了一把,让Attribute跟大家混了个脸儿熟.中篇里,我们将探讨“究竟什么是Attribute”和“如何创建及使用Attribute”这 ...