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 ...
随机推荐
- Vbs脚本经典教材
转载:http://www.cnblogs.com/BeyondTechnology/archive/2011/01/10/1932440.html Vbs脚本经典教材(最全的资料还是MSDN) —为 ...
- 【温故知新】——BABYLON.js学习之路·前辈经验(二)
前言:在上一篇随笔BABYLON.js学习之路·前辈经验(一)中回顾了组内同事们长时间在Babylon开发实践中的总结出的学习之路和经验,这一篇主要对开发中常见的一些功能点做一个梳理,这里只作为温故知 ...
- lnmp环境网页访问慢排查思路
1.首先看每个服务器的负载情况 2.若各个服务器负载不高 首先查看是不是负载均衡服务器问题相接访问web服务看是否慢,若也慢则查看是不是访问动态页面慢,创建一个静态页面访问试试,若不慢则是动态页面问题 ...
- 决策树之 C4.5
C4.5 是对 ID3 的一个优化,它依据信息增益率来进行属性选择. 关于决策树.请參见:http://blog.csdn.net/bone_ace/article/details/46299681 ...
- HDU5294——Tricks Device(最短路 + 最大流)
第一次做最大流的题目- 这题就是堆模板 #include <iostream> #include <algorithm> #include <cmath> #inc ...
- JS函数库Underscore.js
http://underscorejs.org/ http://www.css88.com/doc/underscore/ http://www.bootcss.com/p/underscore/
- C语言的空格问题
对于C语言中,一般的理解是对于空格,我们可以随意输入,因为空格没啥大意义,但是事实上并非如此. 1.'\'空格的问题 '\' 字符可用于一些字符进行转移,当然也包括了 newline(enter),被 ...
- Html5上传插件封装
前段时间将flash的上传控件替换成使用纯js实现的,在此记录 1.创建标签 <div class="camera-area" style="display:inl ...
- Android有关surfaceView又一次创建的问题。
近期在做一个Android视频播放器的项目.遇到一个问题,就是锁屏之后.surfaceview就会被销毁掉,然后就会出现各种错误.到csdn论坛去发帖提问,各种所谓的大神都说,解锁屏在又一次创建一个, ...
- 调试Scrapy过程中的心得体会
1.大量抓取网页时出现“Memory Error”解决办法:设置一个队列,每当爬虫空闲时才向队列中放入请求,例如: from scrapy import signals, Spider from sc ...