题解:链接
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ;i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{
char c;int sign = 1;x = 0;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 2e5+50;
int a[N],n,m;
struct Segment_tree
{
int val[N << 2],as[N<<2],os[N<<2];
int lzy[N << 2][2];
void build(int id,int l,int r)
{
lzy[id][1] = lzy[id][0] = -1;
if(l == r)
{
val[id] = a[l];
as[id] = os[id] = a[l];
return ;
}
int mid = l + r >> 1;
build(id<<1,l,mid); build(id<<1|1,mid+1,r);
val[id] = max(val[id<<1],val[id<<1|1]);
as[id] = as[id<<1]&as[id<<1|1];
os[id] = os[id<<1]|os[id<<1|1];
}
inline void put_down(int id)
{
if(~lzy[id][0])
{
val[id<<1] |= lzy[id][0];
val[id<<1|1] |= lzy[id][0];
as[id<<1] |= lzy[id][0];
as[id<<1|1] |= lzy[id][0];
os[id<<1] |= lzy[id][0];
os[id<<1|1] |= lzy[id][0];
if(~lzy[id<<1][1]) lzy[id<<1][1] |= lzy[id][0];
if(~lzy[id<<1][0]) lzy[id<<1][0] |= lzy[id][0];
else lzy[id<<1][0] = lzy[id][0];
if(~lzy[id<<1|1][1]) lzy[id<<1|1][1] |= lzy[id][0];
if(~lzy[id<<1|1][0]) lzy[id<<1|1][0] |= lzy[id][0];
else lzy[id<<1|1][0] = lzy[id][0];
lzy[id][0] = -1;
}
if(~lzy[id][1])
{
val[id<<1] &= lzy[id][1];
val[id<<1|1] &= lzy[id][1];
as[id<<1] &= lzy[id][1];
as[id<<1|1] &= lzy[id][1];
os[id<<1] &= lzy[id][1];
os[id<<1|1] &= lzy[id][1];
if(~lzy[id<<1][1]) lzy[id<<1][1] &= lzy[id][1];
else lzy[id<<1][1] = lzy[id][1];
if(~lzy[id<<1|1][1]) lzy[id<<1|1][1] &= lzy[id][1];
else lzy[id<<1|1][1] = lzy[id][1];
lzy[id][1] = -1;
}
}
inline int get(int id) { return as[id]^os[id];}
void update(int id,int l,int r,int L,int R,int w,bool k)
{
if(l >= L && r <= R && !(get(id)&w) )
{
if(k)
{
val[id] &= w; as[id] &= w; os[id] &= w;
if(~lzy[id][k]) lzy[id][k] &= w;
else lzy[id][k] = w;
}
else
{
val[id] |= w; os[id] |= w; as[id] |= w;
if(~lzy[id][k^1]) lzy[id][k^1] |= w;
if(~lzy[id][k]) lzy[id][k] |= w;
else lzy[id][k] = w;
}
return ;
}
put_down(id);
int mid = l + r >> 1;
if( L > mid ) update(id<<1|1,mid+1,r,L,R,w,k);
else if(R <= mid) update(id<<1,l,mid,L,R,w,k);
else update(id<<1,l,mid,L,mid,w,k) , update(id<<1|1,mid+1,r,mid+1,R,w,k);
val[id] = max(val[id<<1],val[id<<1|1]);
as[id] = as[id<<1]&as[id<<1|1];
os[id] = os[id<<1]|os[id<<1|1];
}
int query(int id,int l,int r,int L,int R)
{
if(l == L && r == R) return val[id];
put_down(id);
int mid = l + r >> 1;
if( L > mid ) return query(id<<1|1,mid+1,r,L,R);
else if(R <= mid) return query(id<<1,l,mid,L,R);
else return max(query(id<<1,l,mid,L,mid),query(id<<1|1,mid+1,r,mid+1,R));
}
}seg;
int main()
{
read(n); read(m);
rep(i,1,n) read(a[i]);
seg.build(1,1,n);
int op,l,r,x;
rep(i,1,m)
{
read(op); read(l); read(r);
if(op == 1)
{
read(x);
seg.update(1,1,n,l,r,x,1);
}
if(op == 2)
{
read(x);
seg.update(1,1,n,l,r,x,0);
}
if(op == 3)
{
printf("%d\n",seg.query(1,1,n,l,r));
}
}
return 0;
}
本文详细解析了一段涉及区间更新和查询操作的C++代码,该代码利用线段树实现高效的数据结构操作,包括区间与、或运算及最大值查询等功能。
294

被折叠的 条评论
为什么被折叠?



