题目链接: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. 2017.2.21 activiti实战--第十三章--流量数据查询与跟踪(一)查询接口介绍及运行时数据查询

    学习资料:<Activiti实战> 第十三章 流量数据查询与跟踪 本章讲解运行时与历史数据的查询方法.主要包含三种:标准查询,Native查询,CustomSql查询. 13.1 Quer ...

  2. linux下内存

    MMU由一个或一组芯片组成.其功能是把逻辑地址映射为物理地址,进行地址转换(MMU是CPU的一部分) 机器指令仍然用逻辑地址指定一个操作数的地址或一条指令的地址 每个逻辑地址都由一个段选择符(16位) ...

  3. Codeforces Round #243 (Div. 2)——Sereja and Table

    看这个问题之前,能够先看看这个论文<一类算法复合的方法>,说白了就是分类讨论,可是这个思想非常重要 题目链接 题意: 首先给出联通块的定义:对于相邻(上下和左右)的同样的数字视为一个联通块 ...

  4. 【Python】删除字符串的空白

    在程序中,额外的空白可能让人迷惑,对于程序员来说,'python'跟'python '看起来几乎一样,但是对于程序来说,可是千差万别 (lstrip)删除开头空白 >>> Langu ...

  5. Spring学习九----------Bean的配置之Bean的定义及作用域的注解实现

    © 版权声明:本文为博主原创文章,转载请注明出处 Spring Bean常用注解 @Component:通常注解,可用于任何Bean @Repository:通常用于注解DAO层,即持久层 @Serv ...

  6. FZU 2124 FOJ 2124 吃豆人【BFS】

     Problem 2124 吃豆人 Accept: 134    Submit: 575 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  7. 使用java+TestNG进行接口回归测试

    TestNG是一个开源自动化测试框架,“NG”表示下一代(Next Generation的首字母). TestNG类似于JUnit(特别是JUnit 4),但它不是JUnit框架的扩展,相较于Juni ...

  8. 【虚拟机】WIN8.1系统安装虚拟机win7环境

    一.虚拟机的安装 1.准备 VMware Workstation 的软硬件支持,请查看 http://www.vmware.com/cn/products/workstation.html#techs ...

  9. cesium学习--初识

    一.Cesium 官方介绍:CesiumJS是一个开源的JavaScript库,用于世界级的3D地球仪和地图.任务是为静态和时间动态的内容创建领先的3D地球和地图,具有最好的性能.精度.视觉质量.平台 ...

  10. Linux将进程写入开机自启动

    只需将启动的命令写入/etc/rc.local 如让mongodb开机自启动: echo "/usr/local/mongodb/bin/mongod --dbpath=/usr/local ...