- 用線段樹維護原序列對應的差分陣列,可以把區間修改簡化為單點修改
點選檢視程式碼
#include <bits/stdc++.h>
using namespace std;
int a[100005],n;
int read1()
{
char cc=getchar();
while(!(cc>=48&&cc<=57))
{
if(cc=='-')
{
break;
}
cc=getchar();
}
bool f=false;
int s=0;
if(cc=='-')
{
f=true;
}
else
{
s=cc-48;
}
while(1)
{
cc=getchar();
if(cc>=48&&cc<=57)
{
s=s*10+cc-48;
}
else
{
break;
}
}
if(f==true)
{
s=-s;
}
return s;
}
struct t1
{
int l,r;
long long u,v,bj;
bool fs,fu,fd;
long long va;
}t[400005];
void update(int p)
{
t[p].u=t[p*2].u;t[p].v=t[p*2+1].v;
t[p].fu=(t[p*2].fu&&t[p*2+1].fu&&t[p*2].v<t[p*2+1].u);
t[p].fd=(t[p*2].fd&&t[p*2+1].fd&&t[p*2].v>t[p*2+1].u);
long long lv=t[p*2].va,rv=t[p*2+1].va;
t[p].fs=(lv==rv&&t[p*2].fs&&t[p*2+1].fs);
if(t[p].fs)
{
t[p].va=lv;
}
else
{
t[p].va=-1;
}
}
void spread(int p)
{
long long bj=t[p].bj;
t[p].bj=0;
t[p*2].bj+=bj;
t[p*2+1].bj+=bj;
t[p*2].u+=bj;t[p*2].v+=bj;
t[p*2+1].u+=bj;t[p*2+1].v+=bj;
if(t[p*2].fs)
{
t[p*2].va+=bj;
}
if(t[p*2+1].fs)
{
t[p*2+1].va+=bj;
}
}
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].va=t[p].u=t[p].v=a[l];
t[p].fs=t[p].fu=t[p].fd=true;
return;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
update(p);
}
bool asks(int p,int l,int r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].fs;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
bool va=true;
long long lv,rv;
if(l<=mid)
{
va=va&asks(p*2,l,r);
lv=t[p*2].v;
}
if(r>mid)
{
va=va&asks(p*2+1,l,r);
rv=t[p*2+1].u;
}
if(l<=mid&&r>mid)
{
va=va&(lv==rv);
}
return va;
}
bool asku(int p,int l,int r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].fu;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
bool va=true;
long long lv,rv;
if(l<=mid)
{
va=va&asku(p*2,l,r);
lv=t[p*2].v;
}
if(r>mid)
{
va=va&asku(p*2+1,l,r);
rv=t[p*2+1].u;
}
if(l<=mid&&r>mid)
{
va=va&(lv<rv);
}
return va;
}
bool askd(int p,int l,int r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].fd;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
bool va=true;
long long lv,rv;
if(l<=mid)
{
va=va&askd(p*2,l,r);
lv=t[p*2].v;
}
if(r>mid)
{
va=va&askd(p*2+1,l,r);
rv=t[p*2+1].u;
}
if(l<=mid&&r>mid)
{
va=va&(lv>rv);
}
return va;
}
void change(int p,int l,int r,int x)
{
if(l<=t[p].l&&r>=t[p].r)
{
t[p].bj+=x;
t[p].u+=x;
t[p].v+=x;
if(t[p].fs)
{
t[p].va+=x;
}
}
else
{
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)
{
change(p*2,l,r,x);
}
if(r>mid)
{
change(p*2+1,l,r,x);
}
update(p);
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
a[i]=read1();
}
build(1,1,n);
int q;
cin>>q;
for(int i=1;i<=q;i++)
{
int opt,l,r;
opt=read1();
l=read1();
r=read1();
if(opt==1)
{
int x=read1();
change(1,l,r,x);
}
else if(opt==2)
{
printf("%d\n",asks(1,l,r));
}
else if(opt==3)
{
printf("%d\n",asku(1,l,r));
}
else if(opt==4)
{
printf("%d\n",askd(1,l,r));
}
else if(opt==5)
{
int tl=l,tr=r;
l++;
r--;
bool pd=true;
while(l<r)
{
int mid=(l+r)>>1;
bool pl=asku(1,tl,mid);
bool pr=askd(1,mid,tr);
if(pl==pr&&pr==true)
{
break;
}
else if(pl==true)
{
l=mid+1;
}
else if(pr==true)
{
r=mid-1;
}
else
{
pd=false;
break;
}
}
if(l>r)
{
pd=false;
}
else if(l==r)
{
pd=(asku(1,tl,l)&askd(1,r,tr));
}
printf("%d\n",pd);
}
}
return 0;
}