#include<cstdio>
#define inf -2147483648ll
#define int long long
struct maxrange{
int left,right,all;
maxrange(void)=default;
maxrange(int left,int right,int all){
this->left=left;
this->right=right;
this->all=all;
};
inline bool operator==(maxrange other){
if(other.left==left&&other.right==right&&other.all==all){
return true;
};
return false;
};
};
struct node{
int sum,as;
maxrange range;
node(void)=default;
node(int sum,int as,maxrange range){
this->sum=sum;
this->as=as;
this->range=range;
};
inline bool operator==(node other){
if(other.sum==sum&&other.as==as&&other.range==range){
return true;
};
return false;
};
};
node tree[100001<<2];
inline int max(int first,int second){
if(first>second){
return first;
};
return second;
};
inline int min(int first,int second){
if(first<second){
return first;
};
return second;
};
inline node max(node first,node second){
if(first==node(inf,inf,maxrange(inf,inf,inf))){
return second;
};
if(second==node(inf,inf,maxrange(inf,inf,inf))){
return first;
};
node result;
result.sum=first.sum+second.sum;
result.as=first.as&second.as;
result.range.left=max(first.range.left,first.sum+second.range.left);
result.range.right=max(second.sum+first.range.right,second.range.right);
result.range.all=max(max(first.range.all,second.range.all),first.range.right+second.range.left);
return result;
};
inline void pushup(int root){
tree[root]=max(tree[root<<1],tree[root<<1|1]);
return;
};
inline void build(int root,int first,int last){
if(first==last){
scanf("%lld",&tree[root].sum);
tree[root].as=tree[root].range.left=tree[root].range.right=tree[root].range.all=tree[root].sum;
};
int middle=first+last>>1ll;
build(root<<1ll,first,middle);
build(root<<1ll|1ll,middle+1ll,last);
pushup(root);
return;
};
inline void change(int root,int first1,int last1,int first2,int last2,int as){
if(first2<first1||last1<last2||(tree[root].as|as)==tree[root].as){
return;
};
if(first1==last1){
tree[root].as|=as;
tree[root].sum=tree[root].range.left=tree[root].range.right=tree[root].range.all=tree[root].as;
};
int middle=first1+last1>>1ll;
change(root<<1ll,first1,middle,first2,last2,as);
change(root<<1ll|1ll,middle+1ll,last1,first2,last2,as);
pushup(root);
return;
};
inline node query(int root,int first1,int first2,int last1,int last2){
if(first2<first1||last1<last2){
return node(inf,inf,maxrange(inf,inf,inf));
};
if(first1<=first2&&last2<=last1){
return tree[root];
};
int middle=first1+last1>>1ll;
return max(query(root<<1ll,first1,middle,first2,last2),query(root<<1ll|1ll,middle+1ll,last1,first2,last2));
};
signed main(signed argc,char **argv){
int size,action;
scanf("%lld %lld",&size,&action);
build(1ll,1ll,size);
do{
int symbol,first,last;
scanf("%lld %lld %lld",&symbol,&first,&last);
if(symbol==1ll){
printf("%lld\n",max(0ll,query(1ll,1ll,size,min(first,last),max(first,last)).range.all));
}else{
int as;
scanf("%lld",&as);
change(1ll,1ll,size,first,last,as);
};
}while(--action);
return 0;
};
目前已知,build 肯定出了问题,但是调不出来哪里有问题。