链接:点击打开链接
四个操作,或,与,异或,求和。成段更新。
如果相邻两个数经过操作之后变成相同的数了,那么再经过覆盖了该区间的操作时,那么他们的值将同时发生改变,变成另外一个相同的值,这多次操作下去,之后将生更多的相同的数字区间,这里的相同数字就是懒惰标记更新的关键:例如:OR 6 0 3, A=[6 6 6 7]; 其中6出现了3次
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 1000010
struct node{
int l;
int r;
int cover;
}anode[N*4];
int data[N];
void pushdown(int n){
if(anode[n].cover!=-1){
//anode[n].sum=anode[n].cover*(anode[n].r-anode[n].l+1);
anode[2*n].cover=anode[2*n+1].cover=anode[n].cover;
anode[n].cover=-1;
return;
}
}
void pushup(int n){
if(anode[2*n].cover==anode[2*n+1].cover&&anode[2*n].cover!=-1)
anode[n].cover=anode[2*n].cover;
}
void bulid(int l,int r,int n){
int mid;
mid=(l+r)>>1;
anode[n].l=l;
anode[n].r=r;
anode[n].cover=-1;
if(l==r){
anode[n].cover=data[l];
return;
}
bulid(l,mid,2*n);
bulid(mid+1,r,2*n+1);
if(anode[2*n].cover==anode[2*n+1].cover&&anode[n].cover!=-1)
anode[n].cover=anode[2*n].cover;
}
void updateAND(int l,int r,int n,int c){
int mid;
if(anode[n].l==l&&anode[n].r==r&&anode[n].cover!=-1){
anode[n].cover&=c;
//printf("%d\n",anode[n].cover);
return;
}
pushdown(n);
mid=(anode[n].l+anode[n].r)>>1;
if(r<=mid)
updateAND(l,r,2*n,c);
else if(l>mid)
updateAND(l,r,2*n+1,c);
else{
updateAND(l,mid,2*n,c);
updateAND(mid+1,r,2*n+1,c);
}
pushup(n);
}
void updateXOR(int l,int r,int n,int c){
int mid;
if(anode[n].l==l&&anode[n].r==r&&anode[n].cover!=-1){
anode[n].cover^=c;
//printf("%d\n",anode[n].cover);
return;
}
pushdown(n);
mid=(anode[n].l+anode[n].r)>>1;
if(r<=mid)
updateXOR(l,r,2*n,c);
else if(l>mid)
updateXOR(l,r,2*n+1,c);
else{
updateXOR(l,mid,2*n,c);
updateXOR(mid+1,r,2*n+1,c);
}
pushup(n);
}
void updateOR(int l,int r,int n,int c){
int mid;
if(anode[n].l==l&&anode[n].r==r&&anode[n].cover!=-1){
anode[n].cover|=c;
// printf("%d\n",anode[n].cover);
return;
}
pushdown(n);
mid=(anode[n].l+anode[n].r)>>1;
if(r<=mid)
updateOR(l,r,2*n,c);
else if(l>mid)
updateOR(l,r,2*n+1,c);
else{
updateOR(l,mid,2*n,c);
updateOR(mid+1,r,2*n+1,c);
}
pushup(n);
}
int query(int l,int r,int n){
int mid;
mid=(anode[n].l+anode[n].r)>>1;
if(anode[n].l==l&&anode[n].r==r&&anode[n].cover!=-1)
return anode[n].cover*(anode[n].r-anode[n].l+1);
pushdown(n);
if(r<=mid)
return query(l,r,2*n);
else if(l>mid)
return query(l,r,2*n+1);
else return query(l,mid,2*n)+query(mid+1,r,2*n+1);
pushup(n);
}
int main(){
int t,n,m,a,b,c,i;
char str[10];
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&data[i]);
bulid(1,n,1);
//for(i=1;i<=7;i++)
//printf("%d ",anode[i].sum);
//for(i=1;i<=7;i++)
//printf("%d ",anode[i].cover);
while(m--){
scanf("%s",str);
if(!strcmp(str,"SUM")){
scanf("%d %d",&a,&b);
int ans=query(a+1,b+1,1);
printf("%d\n",ans);
}
else if(!strcmp(str,"XOR")){
scanf("%d %d %d",&c,&a,&b);
updateXOR(a+1,b+1,1,c);
}
else if(!strcmp(str,"OR")){
scanf("%d %d %d",&c,&a,&b);
updateOR(a+1,b+1,1,c);
}
else if(!strcmp(str,"AND")){
scanf("%d %d %d",&c,&a,&b);
updateAND(a+1,b+1,1,c);
}
}
}
return 0;
}