题目链接:https://vjudge.net/problem/CodeChef-ANDMIN

Read problems statements in Mandarin ChineseRussian 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 —— 线段树 (结点最多被修改的次数)的更多相关文章

  1. 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数

    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...

  2. HDU1698 线段树入门之区间修改/查询(lazy标记法)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. codevs1081 线段树练习 2<区间修改>

    1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master   题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有 ...

  4. 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 ...

  5. 最大数maxnumber (HYSBZ 1012)(线段树区间查询和单点修改)(优雅的暴力)

    Problem 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L 个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作 ...

  6. 2020牛客寒假算法基础集训营2 J.求函数 (线段树 推公式 单点修改 区间查询)

    https://ac.nowcoder.com/acm/contest/3003/J 题解: #include<bits/stdc++.h> typedef long long ll; u ...

  7. 【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****

    [codevs2216]行星序列 2014年2月22日3501 题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小 ...

  8. kb-07线段树-05-区间整体修改查询;(水)

    /* */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; s ...

  9. 【codevs】1082 线段树练习 3 <区间修改+区间和>

    题目连接   http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...

随机推荐

  1. linux 打开文件数too many open files解决方法

    出现这句提示的原因是程序打开的文件/socket连接数量超过系统设定值.查看每个用户最大允许打开的文件数量ulimit -a 其中 open files (-n) 1024 表示每个用户最大允许打开的 ...

  2. Struts2 convention插件试用+ Spring+Hibernate SSH整合

    第一步,引入struts2-convention-plugin-2.2.1.jar 然后,改动配置文件. 我是在struts.properties文件里改动的: struts.objectFactor ...

  3. Android开发之布局文件里实现OnClick事件关联处理方法

    一般监听OnClickListener事件,我们都是通过Button button = (Button)findViewById(....); button.setOClickLisener....这 ...

  4. 从有序数组中查找某个值 low_bound

    二分搜索 题意: 给定长度为n的单调不下降数列a0, ...an-1和一个数k,求满足ai>=k条件的最小的i. 不存在的情况下输出n. 输入: 5        3 2 3 3 5 6 输出: ...

  5. STL源代码分析--第二级空间配置器

    本文解说SGI STL空间配置器的第二级配置器. 相比第一级配置器,第二级配置器多了一些机制,避免小额区块造成内存的碎片.不不过碎片的问题,配置时的额外负担也是一个大问题.由于区块越小,额外负担所占的 ...

  6. 【Python】字典~深入篇

    字典的定义 字典是一系列键值对,字典用放在{}一系列键值对表示 info = {','city':'KunMing'} 字典增.删.改.查 增加新元素 指定字典名,用方括号括起来的键和相关的值 inf ...

  7. javascript if(条件)------------条件中可以使用的值

    1.布尔变量true/false2.数字非0,非NaN/ ( 或NaN) NaN--------Not a Number 3.对象非null/(null或undefined) 4.字符串非空串(&qu ...

  8. Oracle 优化器

    http://blog.csdn.net/it_man/article/details/8185370一.优化器基本知识   Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执 ...

  9. iPhone换电池是原装电池好还是换第三方大容量电池好?

    转:https://www.xianjichina.com/news/details_60791.html 最近这段时间苹果降速门事件持续发酵,闹得满城风雨.尽管苹果公司两次致歉,很多果粉都去更换电池 ...

  10. python thrift hbase安装连接

    默认已装好 hbase,我的版本是hbase-0.98.24,并运行 python 2.7.x 步骤: sudo apt-get install automake bison flex g++ git ...