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 题目描述 给定长度为 N 的整数序列。你需要支持如下操作: • 0 L R:查询序列在区间 [L, R] 中的最小值; • 1 L R X:对于序列在区间 [L, R] 中的每个元素 Ai,执行操作:Ai ← Ai&X,其中 & 为按 位与操作。 分析 区间查询最小值可以用线段树,这道题麻烦的是更新操作,若是对区间里每个数都按位与一遍,必定会超时。这时不要慌,稳定分析,&按位与有个特点,即该数的二进制表示为某位为0的话,此后的所以更新,都不会改变该位为0的事实。这样我们可以计算这个区间究竟最多能进行多少次&操作?即区间内每个数的每个对应位上1的总数,若某次进行&x操作时,检测一下会不会对区间造成影响,若不会,就此打住,这样就避免了许多无用操作,不必每次都更新到叶子结点上。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #include<cstring> #include <queue> #include <vector> #include<bitset> #include<map> #include<deque> using namespace std; typedef long long LL; const int maxn = 1e5+5; const int mod = 77200211+233; typedef pair<int,int> pii; #define X first #define Y second #define pb push_back //#define mp make_pair #define ms(a,b) memset(a,b,sizeof(a)) const int inf = 0x3f3f3f3f; #define lson l,m,2*rt #define rson m+1,r,2*rt+1 struct node{ int a; int l,r; int st; int mid(){ return (l+r)>>1; } }tree[maxn<<2]; void pushup(int rt){ tree[rt].a = min(tree[rt<<1].a,tree[rt<<1|1].a); tree[rt].st = tree[rt<<1].st | tree[rt<<1|1].st; } void build(int l,int r,int rt){ tree[rt].l=l,tree[rt].r=r; if(l==r){ scanf("%d",&tree[rt].a); tree[rt].st=tree[rt].a; return; } int m=tree[rt].mid(); build(l,m,rt<<1); build(m+1,r,rt<<1|1); pushup(rt); } void update(int l,int r,int x,int rt){ if(l<= tree[rt].l && r>= tree[rt].r){ int t = tree[rt].st&x; if(t==tree[rt].st) return; } if(tree[rt].l==tree[rt].r){ tree[rt].a = tree[rt].a & x; tree[rt].st=tree[rt].a; return; } int m = tree[rt].mid(); if(l<=m) update(l,r,x,rt<<1); if(r>m) update(l,r,x,rt<<1|1); pushup(rt); } int query(int l,int r,int rt){ if(l<= tree[rt].l && r>= tree[rt].r){ return tree[rt].a; } int m=tree[rt].mid(); int ans=inf; if(l<=m) ans=min(ans,query(l,r,rt<<1)); if(r>m) ans=min(ans,query(l,r,rt<<1|1)); return ans; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ build(1,n,1); while(m--){ int x,l,r; scanf("%d",&x); if(x){ int l,r; scanf("%d%d%d",&l,&r,&x); update(l,r,x,1); }else{ scanf("%d%d",&l,&r); cout<<query(l,r,1)<<endl; } } } return 0; }
原文地址:https://www.cnblogs.com/fht-litost/p/8654722.html
时间: 2024-11-05 16:27:19