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 ...
随机推荐
- hdu 5339 Untitled【搜索】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5339 题意:一个整数a 和一个数组b.问你能否在b中取出r个元素排列组成c数组满足a%c1%c1%-. ...
- 1毛钱的CDN你家的站点会用吗?
在第七届中国云计算大会上,作为CDN领域最具重量级的受邀发言人.迅雷CTO.网心科技CEO陈磊在发表重要演讲时,宣布迅雷将推出国内首家无限节点CDN.而这一款CDN号称眼下国内最廉价的CDN,售价仅为 ...
- Notification(二)——PendingIntent的flag导致数据同样的问题
MainActivity例如以下: package cc.cu; import android.os.Bundle; import android.view.View; import android. ...
- 手动脱Mole Box壳实战总结
作者:Fly2015 这个程序是吾爱破解脱壳练习第8期的加壳程序,该程序的壳是MoleBox V2.6.5壳,这些都是广告,能够直接无视了.前面的博客手动脱Mole Box V2.6.5壳实战中已经给 ...
- Java数据结构和算法(四)——栈
stack,中文翻译为堆栈,事实上指的是栈,heap,堆. 这里讲的是数据结构的栈,不是内存分配里面的堆和栈. 栈是先进后出的数据的结构,好比你碟子一个一个堆起来.最后放的那个是堆在最上面的. 队列就 ...
- apue学习笔记(第七章 进程环境)
本章将了解进程的环境. main函数 C程序总是从main函数开始执行,main函数的原型是: int main(int argc,char *argv[]); 其中,argc是命令行参数的数目,ar ...
- 为什么我们有时不用配置java环境变量?
答案都在这个图中 完毕,如果还不懂请自行查询注册表相关内容学习.
- ssh登录慢的解决办法
ubuntu的ssh登录有点慢,其实是很慢 google了一把,发现可以这样解决: (1)可能是DNS反向解析的问题 对于这样的问题,可以在/etc/ssh/sshd_config 中添加/修改: U ...
- robotframe使用之时间控件
robotframe使用之时间控件 正常的页面,时间控件会写在一个iframe里面,所以robotframework找不到对的ID或者xpath等. 要解决这个问题必选先显示iframe. 使用关键字 ...
- 【Android】怎样写一个JsBridge
JsBridge 简单介绍 Android JsBridge 就是用来在 Android app的原生 java 代码与 javascript 代码中架设通信(调用)桥梁的辅助工具. 原文地址点这里 ...